#version 440 out vec4 FragColor; in vec2 TexCoords; in vec3 fragPos; in vec3 fragNormal; in vec4 fragPosLightSpace; uniform vec3 Kd; uniform vec3 Ka; uniform vec3 Ks; uniform float Shininess; struct LightInfo { vec4 Position; vec3 Intensity; }; uniform LightInfo Light[64]; uniform int LightCount; uniform uint hasTextureDiffuse; uniform sampler2D tex; uniform sampler2D depth_tex; float ShadowCalculation(vec4 PInLightSpace) { // perform perspective divide vec3 projCoords = PInLightSpace.xyz / PInLightSpace.w; // transform to [0,1] range projCoords = projCoords * 0.5 + 0.5; //why? because it has a values [-1, 1], convert to [0, 1] // get closest depth value from light's perspective (using [0,1] range fragPosLight as coords) float closestDepth = texture(depth_tex, projCoords.xy).r; // get depth of current fragment from light's perspective float currentDepth = projCoords.z; // check whether current frag pos is in shadow float bias = 0.005; float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0; // Supress the limit of the far / close plane if (projCoords.z > 1.0) shadow = 0.0; return shadow; } void main() { //calculate diffuse, specular, ambient vec3 c = vec3(1.0); if (hasTextureDiffuse == 1) { c = texture(tex, TexCoords).rgb; } float shadow = ShadowCalculation(fragPosLightSpace); vec3 L = normalize(Light[LightCount - 1].Position.xyz - fragPos); vec3 N = fragNormal; vec3 V = normalize(-fragPos); //vec3 R = normalize(reflect(-L, N)); vec3 H = normalize(V + L); vec3 ambient = Ka * Light[LightCount - 1].Intensity; vec3 diffuse = Kd * Light[LightCount - 1].Intensity * max(dot(L, N), 0.0); vec3 specular = Ks * Light[LightCount - 1].Intensity * pow(max(dot(H, N), 0.0), Shininess); vec3 final = (ambient + (1-shadow)*(diffuse + specular))*c; FragColor = vec4(final,1.0); }