Shadow Mapping issue

I’ll start off with an image of what my shadows look like currently:

And another image for good measure

As you see, I’m getting some shadows but they are completely in the wrong place, and also completely the wrong size. I’ve pulled my hair out looking at the code so I’m wondering if anyone knows my problem.

Heres my code that sets up the frame buffer and depth buffer stuff:

void Viewer::set_up_shadow_map()
{
	//we want to render our map in a higher resolution
	  int shadow_map_width = get_width() * 2;
	  int shadow_map_height = get_height() * 2;

	  GLenum frame_buffer_status;

	  glGenTextures(1, &depth_tex_id);
	  glBindTexture(GL_TEXTURE_2D, depth_tex_id);


	  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

	  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
	  glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );

	  glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadow_map_width, shadow_map_height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
	  glBindTexture(GL_TEXTURE_2D, 0);
	  // create a framebuffer object
	  glGenFramebuffersEXT(1, &frame_tex_id);
	  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frame_tex_id);

	  glDrawBuffer(GL_NONE);
	  glReadBuffer(GL_NONE);

	  // attach the texture to FBO depth attachment point
	  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,GL_TEXTURE_2D, depth_tex_id, 0);

	  frame_buffer_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
	  if(frame_buffer_status != GL_FRAMEBUFFER_COMPLETE_EXT)
		  std::cout<<"loading frame buffer failed"<<std::endl;

	  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}

I’m fairly certain there’s nothing wrong there.

Here’s what my shadow pass looks like:


  /*
   * all the shadow passes start here
   */

  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,frame_tex_id);	//Rendering offscreen
  glUseProgram(0);
  glViewport(0,0,get_width() * 2,get_height()* 2);
  glClear( GL_DEPTH_BUFFER_BIT);
  glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  set_up_for_drawing(Vector3D(0,0,10), Vector3D(0, 0, 0));
  glCullFace(GL_FRONT);
  draw_fire_pieces(false);
  draw_pieces(false);

Pretty straightforward here, but my set_up_for_drawing simply looks like this:


	  glMatrixMode(GL_PROJECTION);
	  glLoadIdentity();
	  glViewport(0, 0, get_width(), get_height());
	  gluPerspective(40.0, (GLfloat)get_width()/(GLfloat)get_height(), 0.1, 1000.0);

	  // change to model view for drawing
	  glMatrixMode(GL_MODELVIEW);
	  glLoadIdentity();
	  gluLookAt(pos[0],pos[1],pos[2],look[0],look[1],look[2],0,1,0);
//	  gluLookAt(0,0,5,0,0,0,0,1,0);

Again I don’t see where I could be wrong here. After my shadow pass I set up the texture as so:


	static double projection[16];
	static double model_view[16];

	//maps from the unit cube to 0,1
	const GLdouble mapper[16] = {
		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};

	glGetDoublev(GL_MODELVIEW_MATRIX, model_view);
	glGetDoublev(GL_PROJECTION_MATRIX, projection);


	glMatrixMode(GL_TEXTURE);
	glActiveTexture(GL_TEXTURE7);

	glLoadIdentity();
	glLoadMatrixd(mapper);

	glMultMatrixd (projection);
	glMultMatrixd (model_view);

	// Go back to normal matrix mode
	glMatrixMode(GL_MODELVIEW);

Next I simply render my scene as I normally would. Now, I have hierarchical hierarchical models so the way I change the texture matrix in the models is as follows:

	  glMatrixMode(GL_MODELVIEW);
	  glPushMatrix();
	  glPushName(m_id);

	  //lets multiply the opengl matrix by the translation of our scene
	  glMultMatrixd(m_trans.transpose().begin());
	  glMatrixMode(GL_TEXTURE);
	  glActiveTexture(GL_TEXTURE7);
	  glPushMatrix();
	  glMultMatrixd(m_trans.transpose().begin());

	  //now we go through and call walk on the children
	  for (ChildList::const_iterator children = m_children.begin(); children != m_children.end(); ++children)
	  {
	    (*children)->walk_gl(picking);
	  }
	  glPopName();
	  glMatrixMode(GL_MODELVIEW);
	  glPopMatrix();
	  glMatrixMode(GL_TEXTURE);
	  glPopMatrix();

I merely subject the texture matrix to the same transformations that the model goes through.

The method I’m using was in this blog post:

http://fabiensanglard.net/shadowmapping/index.php

I know its a lot of code but any help is greatly appreciated!

Your shadow map texture creating may be wrong

glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadow_map_width, shadow_map_height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);

should be


glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, shadow_map_width, shadow_map_height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INTEGER, 0);

If you are using a depth texture with stencil, then GL_DEPTH_COMPONENT becomes GL_DEPTH_STENCIL and GL_DEPTH_COMPONENT24 becomes GL_DEPTH24_STENCIL8.

Now, then rendering to the shadow map, you are supposed to be rendeing the scene from the light’s Pint Of View (POV).
That means…

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, get_width(), get_height());
gluPerspective(40.0, (GLfloat)get_width()/(GLfloat)get_height(), 0.1, 1000.0);
// change to model view for drawing
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(pos[0],pos[1],pos[2],look[0],look[1],look[2],0,1,0);

…should be using the projection and modelview matricies from the active light. If can’t tell from your code if you have done this.
For example, I don’t see you setting the view port to the dimensions of the shadow FBO (shadow_map_width,shadow_map_height)

The next phase is ‘applying the shadow map’ - ie reading from the shadowmap texture and performing a depth comparison.
I can see you have setup a matrix to contain:
scaleBias * projection * modelview matrix.

…but,again, are these the light’s projection and modelview matricies?
Also, where’s the shader which performs the shadow map comparison?

Thanks! I got it working. My issue was that I call glViewPort but I don’t multiply by 2 right before drawing to the frame buffer (i was rendering the shadows at twice the resolution).

In general there is no reason to use twice the resolution for shadow maps. It is more common to pick some nice square, power of two resolution such as 1024 x 1024 or 2048 x 2048.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.