1
\$\begingroup\$

I am implementing hardware shadow mapping as described here.

I've rendered the scene successfully from the light POV, and loaded the depth buffer of the scene into a texture. This texture has correctly been loaded - I check this by rendering a small thumbnail, as you can see in the screenshot below, upper left corner. The depth of the scene appears to be correct - objects further away are darker, and that are closer to the light are lighter.

However, I run into trouble while rendering the scene from the camera's point of view using the depth texture - the texture on the polygons in the scene is rendered in a weird, nondeterministic fashion, as shown in the screenshot. I believe I am making an error while computing the texture transformation matrix, but I am unsure where exactly.

Since I have no matrix utilities in JOGL other then the gl[Load|Mult]Matrix procedures, I multiply the matrices using them, like this:

void calcTextureMatrix() {
  glPushMatrix();

  glLoadIdentity();
  glLoadMatrixf(biasmatrix, 0);
  glMultMatrixf(lightprojmatrix, 0);
  glMultMatrixf(lightviewmatrix, 0);
  glGetFloatv(GL_MODELVIEW_MATRIX, shadowtexmatrix, 0);

  glPopMatrix();
}

I obtained these matrices by using the glOrtho and gluLookAt procedures:

  glLoadIdentity()
  val wdt = width / 45
  val hgt = height / 45
  glOrtho(wdt, -wdt, -hgt, hgt, -45.0, 45.0)
  glGetFloatv(GL_MODELVIEW_MATRIX, lightprojmatrix, 0)

  glLoadIdentity()
  glu.gluLookAt(
    xlook + lightpos._1, ylook + lightpos._2, lightpos._3,
    xlook, ylook, 0.0f,
    0.f, 0.f, 1.0f)
  glGetFloatv(GL_MODELVIEW_MATRIX, lightviewmatrix, 0)

My bias matrix is:

float[] biasmatrix = new float[16] {
  0.5f, 0.f, 0.f, 0.f,
  0.f, 0.5f, 0.f, 0.f,
  0.f, 0.f, 0.5f, 0.f,
  0.5f, 0.5f, 0.5f, 1.f
}

After applying the camera projection and view matrices, I do:

glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR)
glTexGenfv(GL_S, GL_EYE_PLANE, shadowtexmatrix, 0)
glEnable(GL_TEXTURE_GEN_S)

for each component.

Does anybody know why the texture is not being rendered correctly?

Thank you.

scene

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

Multiplying the matrices that way does not work.

Instead, using the Java JAMA package for matrices:

  import Jama._

  Matrix bi = new Matrix(4, 4);
  Matrix lp = new Matrix(4, 4);
  Matrix lv = new Matrix(4, 4);
  Matrix cv = new Matrix(4, 4);

  // store the float arrays to matrices

  Matrix st = bi.times(lp).times(lv)

  // read matrix into float array and transpose.

Interestingly, the shadow texture matrix also had to be transposed.

Still, the resulting image is shown below - it has artifacts. Question is - how to get rid of them?

scene with artifacts

EDIT:

Apparently, the problem is erroneous self-shadowing.

I realized this while reading the suggested link - thanks for the pointer!

However, the links suggests adjusting the near and far planes - this is not the solution. The solution is to adjust the scaling factor of the depth matrix. To avoid peter-panning, the scale in the z-axis should be as big as possible, but less than 1.f:

glMatrixMode(GL_TEXTURE)
glLoadIdentity()
glScalef(1.f, 1.f, 0.9999f)

The result:

scene, no artifacts

I figured it out while going through this example.

\$\endgroup\$
3
  • \$\begingroup\$ Microsoft has an excellent article about improving the quality of your shadow maps: msdn.microsoft.com/en-us/library/windows/desktop/… Jump to "Shadow Acne and Erroneous Self-Shadowing". P.S. It would have been better if you had edited your original question. \$\endgroup\$
    – knight666
    Jul 4, 2012 at 7:07
  • \$\begingroup\$ Thank you for your link, judging from the screenshots there, they attack this problem - I will read this in more detail. I thought about editing the question, but I my thinking was that transposing the matrix might in fact be part of an answer. \$\endgroup\$
    – axel22
    Jul 4, 2012 at 8:10
  • \$\begingroup\$ Their advice is just - make sure that near and far clipping planes are as tight as possible. I think I already made them pretty tight - bringing the far plane further away or the near plane closer results in parts of the depth buffer being at full 1.0 or 0.0. So I think there must be some other solution. \$\endgroup\$
    – axel22
    Jul 4, 2012 at 9:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .