PDA

View Full Version : Shadow Volumes



Phosphor
03-11-2011, 12:10 AM
I am trying to use shadow volumes to cast shadows from a triangle mesh but I am at a loss as to how to get the stencil buffer to increment the pixels on the model.

In the last pass, when I draw the whole scene with the lights on I use
glStencilFunc(GL_EQUAL, 0, -1);

This is what displays when I use back face culling and draw the shadows with
glStencilFunc(GL_NEVER, 1, -1);
and front face culling and draw the shadows with
glStencilFunc(GL_ALWAYS, 1, -1);
http://img847.imageshack.us/img847/7893/neveralways1.png
http://img863.imageshack.us/img863/3858/neveralways.png

It appears to me as though I am never writing to the stencil bits on the model, but rather, that I'm writing to the stencil bits on the shadow volume itself. Is this because of my normals? Am I calculating normals with the wrong light vector? Is it because I'm incrementing bits on the wrong pass?

This is what displays when I use backface culling with
glStencilFunc(GL_ALWAYS, 1, -1);
and frontface culling with
glStencilFunc(GL_NEVER, 1, -1);
http://img852.imageshack.us/img852/9513/alwaysnever.png

And, finally, this is what is displayed when I make no calls to glStencilFunc until the last pass where I draw the whole scene with lights and I call
glStencilFunc(GL_EQUAL, 0, -1);
http://img845.imageshack.us/img845/107/sv4.png
http://img861.imageshack.us/img861/3150/sv3.png
Which is close to what I want except that it seems these shadows are only ever drawn by the stencil bits on the quads that make up the shadow volumes and never by the stencil bits on the model itself.

Phosphor
03-11-2011, 11:21 AM
Here's a bit more information in case someone can see something wrong in my backface/frontface passes. draw_scene() inputs a normal for each triangle and the vertexes of that triangle using glNormal3f then glVertex3f. draw_shadow_volumes() iterates through each pair of vertexes on each triangle, drawing shadow quads from each pair to infinity using glVertex3f(x, y, z) for the vertexes on the model and glVertex4f(x-light_position[0], y-light_position[1], z-light_position[2], 0) for the vertexes at infinity. Thanks for taking a look.

glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glDepthFunc(GL_LEQUAL);

//------DRAW SCENE with lights off
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glEnable(GL_LIGHTING);
glDisable(GL_LIGHT0);
glDisable(GL_LIGHT1);
glEnable(GL_LIGHT1);
draw_scene();
glEnable(GL_CULL_FACE);
glEnable(GL_STENCIL_TEST);

// set to read only
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDepthMask(GL_FALSE);
glDepthFunc(GL_LEQUAL);

//glStencilFunc(GL_ALWAYS, 1, -1);
//glStencilFunc(GL_NEVER, 1, -1);
//------DRAW SHADOW VOLUMES with backface culling
glCullFace(GL_BACK);
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR_WRAP);
draw_shadow_volumes();

//glStencilFunc(GL_ALWAYS, 1, -1);
//glStencilFunc(GL_NEVER, 1, -1);
//------DRAW SHADOW VOLUMES with frontface culling
glCullFace(GL_FRONT);
glStencilOp(GL_KEEP, GL_KEEP, GL_DECR_WRAP);
draw_shadow_volumes();

//------DRAW SCENE with lights on
glCullFace(GL_BACK);
glDisable(GL_CULL_FACE);
// set to write
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_TRUE);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glStencilFunc(GL_EQUAL, 0, -1);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
draw_scene();