forkkmuopengl/BaseGLProject/shadow_light.frag

70 lines
1.9 KiB
GLSL

#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);
}