in vec3 position; in vec2 texcoord; in vec3 normal; uniform highp mat4 modelMatrix; uniform highp mat4 viewMatrix; uniform highp mat4 projMatrix; uniform highp mat4 normalMatrix; uniform vec4 ambientLight; uniform vec4 diffuse; uniform vec4 ambient; uniform float fogStart; uniform float fogEnd; varying float fogFactor; struct Light { vec4 _position; vec4 _direction; vec4 _color; float enabled; }; const int maxLights = 8; uniform Light lights[maxLights]; out vec2 Texcoord; out vec4 Color; out vec3 Normal; void main() { vec4 viewCoords = viewMatrix * modelMatrix * vec4(position, 1.0); gl_Position = projMatrix * viewCoords; Texcoord = texcoord; Color = diffuse; vec3 light = vec3(0.0, 0.0, 0.0); vec3 normalEye = normalize((normalMatrix * vec4(normal, 0.0)).xyz); float fogCoord = abs(viewCoords.z); fogFactor = clamp((fogEnd - fogCoord) / (fogEnd - fogStart), 0.0, 1.0); for (int i = 0; i < maxLights; ++i) { if (lights[i].enabled < 0.0) { continue; } float intensity = 1.0; vec4 lightPosition = viewMatrix * lights[i]._position; vec3 vertexToLight = lightPosition.xyz - viewCoords.xyz; if (lights[i]._direction.w < 0.0) { // Spotlight vec4 lightDirection = viewMatrix * vec4(lights[i]._direction.xyz, 0.0); // See DirectX spotlight documentation float cosAngle = -dot(normalize(vertexToLight), normalize(lightDirection.xyz)); // rho float cosPenumbra = 0.968912; // cos(1 / 4) float cosUmbra = 0.877582; // cos(1 / 2) if (cosAngle <= cosPenumbra) { if (cosAngle < cosUmbra || cosPenumbra == cosUmbra) { intensity = 0.0; } else { intensity *= (cosAngle - cosUmbra) / (cosPenumbra - cosUmbra); } } } intensity *= max(0.0, dot(normalEye, normalize(vertexToLight))); light += lights[i]._color.rgb * intensity; } Color.rgb *= light; Color.rgb += ambient.rgb * ambientLight.rgb; Color.rgb = clamp(Color.rgb, 0.0, 1.0); }