Skip to main content
GameDev.net gamedev.net
🔒 Locked

GLSL Shadow Mapping

Started by playa_151 Apr 27, 2005 at 3:23 PM 7 replies 29k views
Original Post
playa_151
playa_151
I am trying to get shadow mapping to work in my GLSL application. Everything looks fine except that the torus does not render right. The ground is fine. If I don't use shaders and use tex gen everything is perfect. So the problem must be in how I am generating the proj coords. Here is the GLSL shaders I am using...

// VERTEX SHADER
varying vec4 projCoord;
varying vec4 color;

uniform vec4 lightPos;


void main()
{
   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

   vec4 pos = gl_ModelViewMatrix * gl_Vertex;
   vec3 lightVect = normalize(lightPos.xyz - pos.xyz);
   vec3 n = gl_NormalMatrix * gl_Normal;

   projCoord = gl_TextureMatrix[0] * gl_Vertex;
   color = gl_Color * max(dot(n, lightVect), 0);
}

// FRAGMENT SHADER
uniform sampler2D shadowMap;

varying vec4 projCoord;
varying vec4 color;

const vec4 ambient = vec4(0.13);

void main()
{
  vec3 projectiveBiased = (projCoord.xyz / projCoord.w);
 
  float shadowValue = projectiveBiased.z < 0 ? 0 : shadow2D(shadowMap, projectiveBiased).r;

  gl_FragColor = ambient + color * shadowValue;
}
Any help would be apreciated.
playa_151
playa_151
Anyone run into this problem either using Cg or GLSL?
playa_151
playa_151
So no one out there has every done shadow mapping using shaders?
gulgi
gulgi
My GLSL code look like this:

Vertex program:
varying float Diffuse;varying vec2  TexCoord;varying vec4 ProjShadow;uniform vec3 LightDirection;void main(void){	vec3 realNorm   = gl_NormalMatrix * gl_Normal;	Diffuse         = max(dot(-LightDirection, realNorm), 0.0);	TexCoord        = gl_MultiTexCoord0;	ProjShadow	= gl_TextureMatrix[1] * gl_Vertex;	gl_Position	= ftransform();}


Fragment program:
uniform sampler2D Checker;uniform sampler2DShadow ShadowMap;varying vec4 ProjShadow;varying float Diffuse;varying vec2  TexCoord;void main (void){	vec3 color = texture2D(Checker, TexCoord).stp;	color *= shadow2DProj(ShadowMap, ProjShadow).r;	color *= Diffuse;	gl_FragColor = vec4(color, 1);}


Should just work.. (if you set up the texturematrix correctly etc ;])

Good luck..!
playa_151
playa_151
Thanks for responding but it still does not work. This is how I make the texture matrix...

void RenderScene(){   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);   glLoadIdentity();   // Get Light view matrix.   gluLookAt(lightPos[0], lightPos[1], lightPos[2],             0.0f, 2.5f, 0.0f, 0.0f, 1.0f, 0.0f);   glGetFloatv(GL_MODELVIEW_MATRIX, lightViewMat);   // Reset and set to real tranform and rotations.   glLoadIdentity();   glTranslatef(0.0f, -2.0f, -15.0f);   glRotatef(-yRotation, 1.0f, 0.0f, 0.0f);   glRotatef(-xRotation, 0.0f, 1.0f, 0.0f);   // Create the depth/shadow map.   CreateShadowMap();   // Render light source.   glDisable(GL_LIGHTING);   glPushMatrix();      glColor3f(1.0f, 1.0f, 0.0f);      glLightfv(GL_LIGHT0, GL_POSITION, lightPos);      glTranslatef(lightPos[0], lightPos[1], lightPos[2]);      auxSolidSphere(0.1);   glPopMatrix();   glEnable(GL_LIGHTING);   // Create texture matrix.   glMatrixMode(GL_TEXTURE);   glLoadIdentity();   glMultMatrixf(bias);   glMultMatrixf(lightProjMat);   glMultMatrixf(lightViewMat);   glBindTexture(GL_TEXTURE_2D, pBuffer.ID);   if(wglBindTexImageARB(pBuffer.pBufferHandle, WGL_DEPTH_COMPONENT_NV) == FALSE)      return;   // Render the scene with shadow map.   glUseProgramObjectARB(shadowShader);   glUniform1iARB(glslShadowMap, 0);   glUniform4fARB(glslLightPos, lightPos[0], lightPos[1], lightPos[2], 1);   Render();   glUseProgramObjectARB(NULL);   if(wglReleaseTexImageARB(pBuffer.pBufferHandle, WGL_DEPTH_COMPONENT_NV) == FALSE)      return;   SwapBuffers(g_HDC);   if(GetKeyState(VK_LEFT) & 0x80) lightPos[0] -= 0.1f;   if(GetKeyState(VK_RIGHT) & 0x80) lightPos[0] += 0.1f;   if(GetKeyState(VK_UP) & 0x80) lightPos[1] += 0.1f;   if(GetKeyState(VK_DOWN) & 0x80) lightPos[1] -= 0.1f;}


I really doubt the render functions are wrong. The program works just fine if I use tex gen functions instead of shaders. Unless there is something that OpenGL does to the texture matrix that I am not aware of that it does not do when I use shaders. How do you build your texture matrix. I am getting so sick of this problem and this is really ticking me off. Everyday there is something different going wrong with something.
gulgi
gulgi
My function that set's up my texturematrix:
void Shadow::activate_mapping(Light *l){	const GLdouble bias[] = {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};	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);	glMatrixMode(GL_TEXTURE);	glLoadMatrixd(bias);	glMultMatrixd(l->get_proj_matrix());	glMultMatrixd(l->get_model_matrix());	glMatrixMode(GL_MODELVIEW);}

I have no idea of why yours doesn't work...
but this:
// Get Light view matrix.   gluLookAt(lightPos[0], lightPos[1], lightPos[2],             0.0f, 2.5f, 0.0f, 0.0f, 1.0f, 0.0f);   glGetFloatv(GL_MODELVIEW_MATRIX, lightViewMat);   // Reset and set to real tranform and rotations.   glLoadIdentity();   glTranslatef(0.0f, -2.0f, -15.0f);   glRotatef(-yRotation, 1.0f, 0.0f, 0.0f);   glRotatef(-xRotation, 0.0f, 1.0f, 0.0f);   // Create the depth/shadow map.   CreateShadowMap();
.. looks weird. You should just create the shadowmap after you call gluLookAt.. what are those translate & rotates for?

Good luck...

playa_151
playa_151
Rotating the scene with the mouse. The create shadow map can create the map independent of what I have done before it. I'll try to move it around to be sure. Here is the create shadow map function...

void CreateShadowMap(){   if(wglMakeCurrent(pBuffer.hDC, pBuffer.hRC) == FALSE) return;   glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);   glLoadIdentity();   glMatrixMode(GL_PROJECTION);   glLoadIdentity();   glMultMatrixf(lightProjMat);   glMatrixMode(GL_MODELVIEW);   glMultMatrixf(lightViewMat);   glPolygonOffset(2.0f, 4.0f);   glEnable(GL_POLYGON_OFFSET_FILL);   Render();   glDisable(GL_CULL_FACE);   glDisable(GL_POLYGON_OFFSET_FILL);   if(wglMakeCurrent(g_HDC, g_HRC) == FALSE) return;}
gulgi
gulgi
These lines are wrong:
   glMatrixMode(GL_MODELVIEW);   glMultMatrixf(lightViewMat); <--- wrong


You set the camera rotation, then you make changes to the matrices in the createshadow function, then you leave them as that?

Keep track of your matrices, just a few push-pop in the right locations should help a bit.
A camera class etc should help alot.

Good luck.
playa_151
playa_151
That wasn't the problem. I added push/pop and the results are the same. The problem has to be with the texture matrix. If I take out the shader enable code and add texgen functions for the s, t, r, q in its place then everything renders fine. When I add the shaders then things are not 100%.

So what is the tex gen functions affecting that I am not doing in the shaders? Does anyone know how to manually calculated texcoords using eye linear?

[Edited by - playa_151 on April 28, 2005 10:17:44 AM]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.