Reputation: 31
I am trying to implement shadow mapping in my OpenGL engine using this tutorial : http://www.fabiensanglard.net/shadowmapping/index.php
I don't have any problems while making the shadow map (i think ). But using it the scene is totally shadowed.
The way I am rendering my scene is as follows:
GLuint sdepthtex;
GLuint sframebuffer ;
glGenTextures(1, &sdepthtex);
glBindTexture(GL_TEXTURE_2D, sdepthtex);
glTexImage2D(GL_TEXTURE_2D, 0,GL_DEPTH_COMPONENT16, 1024, 1024, 0,GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, sdepthtex, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
displayMessage("Error loading the Depth Framebuffer");
return;
}
The function i use :
Matrix getMVPmatrix(vector3 position,vector3 lookat )
{
glPushMatrix();
double projection[16];
double modelView[16];
SDL_Surface*screen = SDL_GetVideoSurface();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(FOVY,screen->w/screen->h,NEAR,FAR);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
glLoadIdentity();
gluLookAt(position.x,position.y,position.z,lookat.x,lookat.y,lookat.z,0,1,0);
glGetDoublev(GL_MODELVIEW_MATRIX, modelView);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
Matrix m1(projection);
Matrix m2(modelView);
glPopMatrix();
return m1*m2;
}
Vertex Shader:
uniform mat4 shadowMatrix;
void main()
{
gl_Position = shadowMatrix*gl_Vertex;
}
Fragment Shader:
void main(void)
{
gl_FragDepth = gl_FragCoord.z;
}
For my 3 boxes scene, the linearized depth look like this :
http://www.2shared.com/photo/IExy9aUo/Depth.html
So i think the shadowMatrix and the depth rendering are right.
Vertex Shader:
varying vec4 ShadowCoord;
uniform mat4 shadowMatrix;
mat4 biasMatrix = mat4(
0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0
);
void main (void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_FrontColor = gl_Color;
gl_Position = ftransform();
ShadowCoord = biasMatrix*shadowMatrix *vec4(gl_Vertex.xyz,1.0);
}
Fragment Shader:
uniform sampler2D tex;
uniform sampler2D shadowtex;//the non linearized depth texture we made in the 3rd step.
varying vec4 ShadowCoord;
float getShadowFactor(void)
{
vec4 shadowCoordinateWdivide = ShadowCoord / ShadowCoord.w ;
shadowCoordinateWdivide.z += 0.0005;
float distanceFromLight = texture2D(shadowtex,shadowCoordinateWdivide.st).z;
float shadow = 1.0;
if (ShadowCoord.w > 0.0)
shadow = distanceFromLight < shadowCoordinateWdivide.z ? 0.5 :1.0 ;
return shadow ;
}
void main (void)
{
gl_FragColor =texture2D(tex, gl_TexCoord[0].st);
gl_FragColor.rgb *= getShadowFactor() ;//add shadows Here
}
Upvotes: 0
Views: 1699
Reputation: 54632
It looks like your code has an inconsistency between the texture setup and the shader. In the texture setup code, you have this:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
When GL_TEXTURE_COMPARE_FUNC
is not GL_NONE
, you need to use a shadow texture sampler in your shader code. But in your fragment shader, you use a regular sampler for this texture:
uniform sampler2D shadowtex;
This needs to be changed to this to be compatible with the texture settings:
uniform sampler2DShadow shadowtex;
To match the type, shadow2D()
is then used instead of texture2D()
to sample the texture.
The other option is that you keep GL_TEXTURE_COMPARE_FUNC
at its default value of GL_NONE
. This is then consistent with using a sampler2D
for sampling.
Upvotes: 1