1const float CONSTANT_ATTENUATION = 1.0; 2const float LINEAR_ATTENUATION = 0.0; 3const float QUADRATIC_ATTENUATION = 1.0; 4 5in vec3 position; 6in vec2 texcoord; 7in vec4 color; 8in vec3 normal; 9 10uniform highp mat4 modelMatrix; 11uniform highp mat4 viewMatrix; 12uniform highp mat4 projMatrix; 13uniform highp mat4 extraMatrix; 14uniform bool textured; 15uniform bool lightsEnabled; 16uniform highp vec2 texScale; 17 18const int maxLights = 8; 19uniform vec4 lightsPosition[maxLights]; 20uniform vec4 lightsDirection[maxLights]; 21uniform vec4 lightsColor[maxLights]; 22uniform vec4 lightsParams[maxLights]; 23 24struct shadow_info { 25 bool _active; 26 vec3 _color; 27 vec3 _light; 28 vec3 _point; 29 vec3 _normal; 30}; 31 32uniform shadow_info shadow; 33 34out vec2 Texcoord; 35out vec4 Color; 36 37void main() 38{ 39 vec4 pos = modelMatrix * extraMatrix * vec4(position, 1.0); 40 41 // See http://en.wikipedia.org/wiki/Line-plane_intersection 42 if (shadow._active) { 43 pos /= pos.w; 44 vec3 l = pos.xyz - shadow._light; 45 float d = dot(shadow._point - shadow._light, shadow._normal) / dot(l, shadow._normal); 46 vec3 p = shadow._light + d * l; 47 pos = vec4(p, 1.0); 48 } 49 50 vec4 positionView = viewMatrix * pos; 51 gl_Position = projMatrix * positionView; 52 53 if (shadow._active) { 54 Color = vec4(shadow._color, 1.0); 55 } else { 56 Color = color; 57 } 58 59 if (textured) { 60 Texcoord = vec2(0.0, 1.0) + (texcoord / texScale); 61 } else { 62 Texcoord = vec2(0.0, 0.0); 63 } 64 65 vec3 light = vec3(0.0, 0.0, 0.0); 66 vec3 normalEye = normalize((viewMatrix * (modelMatrix * extraMatrix * vec4(normal, 0.0))).xyz); 67 68 for (int i = 0; i < maxLights; ++i) { 69 float intensity = lightsColor[i].w; 70 float light_type = lightsPosition[i].w; 71 if (light_type >= 0.0) { // Not ambient 72 vec3 vertexToLight = lightsPosition[i].xyz; 73 if (light_type > 0.0) { // positional light 74 vertexToLight -= positionView.xyz; 75 float dist = length(vertexToLight); 76 intensity /= CONSTANT_ATTENUATION + dist * (LINEAR_ATTENUATION + dist * QUADRATIC_ATTENUATION); 77 if (lightsDirection[i].w > -1.0) { // Spotlight 78 // See DirectX spotlight documentation 79 float cosAngle = -dot(normalize(vertexToLight), normalize(lightsDirection[i].xyz)); // rho 80 float cosPenumbra = clamp(lightsParams[i].w, 0.0, 1.0); // cos(theta / 2) 81 float cosUmbra = clamp(lightsParams[i].z, 0.0, cosPenumbra); // cos(phi / 2) 82 if (cosAngle <= cosPenumbra) { 83 if (cosAngle < cosUmbra || cosPenumbra == cosUmbra) { 84 intensity = 0.0; 85 } else { 86 intensity *= (cosAngle - cosUmbra) / (cosPenumbra - cosUmbra); 87 } 88 } 89 } 90 } 91 intensity *= max(0.0, dot(normalEye, normalize(vertexToLight))); 92 } 93 light += lightsColor[i].xyz * intensity; 94 } 95 light /= max(1.0, max(max(light.x, light.y), light.z)); 96 Color *= vec4(light, 1.0); 97} 98