#version 130 #define LIGHT_COUNT 2 #define SHADOWS 1 #define MAX_LIGHTS 2 precision highp float; uniform struct Light { vec4 Diffuse; vec4 Specular; vec4 Position; float InverseRadius; } Lights[MAX_LIGHTS]; in vec2 TextureCoordinates0; in vec3 lightVec[LIGHT_COUNT]; in vec3 eyeVec; #ifdef SHADOWS in vec3 shadowVec[LIGHT_COUNT]; #endif uniform sampler2D DiffuseGloss; uniform sampler2D NormalHeight; #ifdef SHADOWS uniform samplerCube ShadowMap; #endif void main() { vec3 eyeVecNormalized = normalize(eyeVec); vec4 diffuse_gloss = texture2D(DiffuseGloss, TextureCoordinates0); vec3 bump = normalize(texture2D(NormalHeight, TextureCoordinates0).xyz * 2.0 - 1.0); vec3 reflectionVec = reflect(-eyeVecNormalized, bump); // Ambient factor (to avoid total darkness in shadow) vec3 lighting = 0.05 * diffuse_gloss.rgb; for (int i = 0; i < LIGHT_COUNT; i++) { float distance = length(shadowVec[i]); float atten = 1.0 - dot(lightVec[i], lightVec[i]); vec4 moments = textureCube(ShadowMap, shadowVec[i]); if (atten > 0.0 && lightVec[i].z > 0.0) { #ifdef SHADOWS if (distance >= moments[i]) { // VSM float variance = max(moments[i + 2] - moments[i] * moments[i], 0.000002); float d = distance - moments[i]; atten *= variance / (variance + d * d); // Plain SM //atten = 0.0; } #endif vec3 lightVecNormalized = normalize(lightVec[i]); float diffuse = clamp(dot(lightVecNormalized, bump), 0.0, 1.0); float specular = pow(clamp(dot(reflectionVec, lightVecNormalized), 0.0, 1.0), gl_FrontMaterial.shininess); lighting += atten * (Lights[i].Diffuse.rgb * diffuse * diffuse_gloss.rgb + Lights[i].Specular.rgb * diffuse_gloss.a * specular); } } gl_FragColor.rgb = lighting; }