Depth Texturing in GLSL
This GLSL shader program is used to enable depth texturing. The depth texture is located under texture unit 5 as shown:
uniform sampler2DShadow texture_5;
Note we had to pass the light's translation matrix in gl_TextureMatrix element 0 as shown:
ShadowCoord = gl_TextureMatrix[0] * gl_Vertex;
Here are the shaders
Vertex Program
varying vec4 diffuse,ambient;
varying vec3 normal,lightDir,halfVector;
varying vec4 ShadowCoord;
void main()
{
ShadowCoord = gl_TextureMatrix[0] * gl_Vertex;
/* first transform the normal into eye space and
normalize the result */
normal = normalize(gl_NormalMatrix * gl_Normal);
/* now normalize the light's direction. Note that
according to the OpenGL specification, the light
is stored in eye space. Also since we're talking about
a directional light, the position field is actually direction */
lightDir = normalize(vec3(gl_LightSource[0].position));
/* Normalize the halfVector to pass it to the fragment shader */
halfVector = normalize(gl_LightSource[0].halfVector.xyz);
/* Compute the diffuse, ambient and globalAmbient terms */
diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient;
ambient += gl_LightModel.ambient * gl_FrontMaterial.ambient;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
Fragment Program
varying vec4 diffuse,ambient;
varying vec3 normal,lightDir,halfVector;
varying vec4 ShadowCoord;
uniform sampler2D texture_0;
uniform sampler2DShadow texture_5;
void main()
{
vec3 n,halfV;
float NdotL,NdotHV;
diffuse = texture2D(texture_0, gl_TexCoord[0].xy);
ambient = vec4(0.0, 0.0, 0.0, 0.0);
vec4 shadowCoordinateWdivide = ShadowCoord / ShadowCoord.w;
shadowCoordinateWdivide.z += 0.0001;
float distanceFromLight = shadow2DProj(texture_5, shadowCoordinateWdivide).a;
vec4 tc = shadowCoordinateWdivide;
/*
MultiSample depth texture
float s = 0.00005;
//float s = 1.0 / 10.0;
//float d = distanceFromLight;
float d1 = shadow2DProj(texture_5, vec4(tc.r+s, tc.g+s, tc.b, tc.a)).a;
float d2 = shadow2DProj(texture_5, vec4(tc.r+s, tc.g-s, tc.b, tc.a)).a;
float d3 = shadow2DProj(texture_5, vec4(tc.r-s, tc.g+s, tc.b, tc.a)).a;
float d4 = shadow2DProj(texture_5, vec4(tc.r-s, tc.g-s, tc.b, tc.a)).a;
float d5 = shadow2DProj(texture_5, vec4(tc.r+s, tc.g, tc.b, tc.a)).a;
float d6 = shadow2DProj(texture_5, vec4(tc.r+s, tc.g, tc.b, tc.a)).a;
float d7 = shadow2DProj(texture_5, vec4(tc.r-s, tc.g, tc.b, tc.a)).a;
float d8 = shadow2DProj(texture_5, vec4(tc.r-s, tc.g, tc.b, tc.a)).a;*/
/* The ambient term will always be present */
vec4 color = ambient;
/* a fragment shader can't write a varying variable, hence we need
a new variable to store the normalized interpolated normal */
n = normalize(normal);
/* compute the dot product between normal and ldir */
NdotL = max(dot(n,lightDir),0.0);
if (NdotL > 0.0) {
color += diffuse * NdotL;
halfV = normalize(halfVector);
NdotHV = max(dot(n,halfV),0.0);
color += gl_FrontMaterial.specular *
gl_LightSource[0].specular *
pow(NdotHV, gl_FrontMaterial.shininess);
}
gl_FragColor = color;
gl_FragColor.a = diffuse.a;
float shadow = 1.0;
if(ShadowCoord.w > 0.0) {
shadow = distanceFromLight < shadowCoordinateWdivide.z ? 0.2 : 1.0 ;
}
gl_FragColor.rgb = shadow * gl_FragColor.rgb;
}
I think it is error somewhere ... :)
ReplyDelete