Sign in to follow this  
b3rs3rk

Strange issue with shadow volumes

Recommended Posts

finally i've finished my shadow volumes demo. Works (i hope...) but there's a strange bug (maybe it's strange for me but not for you ogl-gurus), here's a screen: http://www.neoborn.com/users/b3rs3rk/shadow%20bug.jpg in a nutshell, i don't know why, but it's rendered also the base of the volume, instead of being rendered only the part on the floor. Anyone knows how to fix this? PS: a special thank to rodzilla who helped me a lot with his advices :)

Share this post


Link to post
Share on other sites
It looks like this is simply the result of leaving the shadow volume open at the base. The volume should be a closed surface, so in this case, you'll need to render an extra quad to close off the bottom.

Share this post


Link to post
Share on other sites
looks like both the near and far shadow volume caps are wound the wrong way. Try reversing them...
Then again if you are uisng depth-pass shadows, then you should not be using near/far shadow caps.

Share this post


Link to post
Share on other sites
Hmmm could you post your code ? It's difficult to guess with the screenshot only.
Are you doing z-pass or z-fail ? Still drawing the shadow as a big blended gray quad (not sure but in this case I'd draw caps even in z-pass mode) ?

Please help us so we can help you ;*)

Share this post


Link to post
Share on other sites
in my render function I clear the buffers, draw the scene (a simple room and a shadow caster quad) and then i do these passes:


glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
glStencilFunc( GL_ALWAYS, 0, 255 );
glDisable( GL_LIGHTING );
glDepthMask( GL_FALSE );
glDepthFunc( GL_LEQUAL );
glEnable( GL_CULL_FACE );
glEnable( GL_STENCIL_TEST );

glCullFace(GL_BACK);
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
Quad.DrawShadow(LightPos,100);
glCullFace(GL_FRONT);
glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
Quad.DrawShadow(LightPos,100);

glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
glDepthMask( GL_TRUE );
glCullFace( GL_BACK );
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glStencilFunc( GL_EQUAL, 0, 255 );

glColor4f( 0.0f, 0.0f, 0.0f, 0.5f );
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glPushMatrix();
glLoadIdentity();
glBegin( GL_TRIANGLE_STRIP );
glVertex3f(-0.1f, 0.1f,-0.10f);
glVertex3f(-0.1f,-0.1f,-0.10f);
glVertex3f( 0.1f, 0.1f,-0.10f);
glVertex3f( 0.1f,-0.1f,-0.10f);
glEnd();
glPopMatrix();

glDisable( GL_BLEND );
glDisable( GL_STENCIL_TEST );
glDisable( GL_CULL_FACE );

Share this post


Link to post
Share on other sites
OK, seems you're doing z-pass.
Do you draw caps for your shadow volume (I'm pretty sure you don't) ?

A solution for your problem would be to draw caps. A better one (to me) would be to make sure you draw shadows on objects only (the problem on your screenshot is shadow that's cast "in the air"). You could use the z-buffer for this : objects are wherever the z value is smaller than 1.0.

The following (before drawing your shadow quad) would (I think) do the trick :

glDepthRange(1.0, 1.0); // make sure the shadow quad is at 1.0
glEnable(GL_DEPTH_TEST); // test the depth
glDepthMask(GL_FALSE); // but don't write
glDepthFunc(GL_GREATER); // and draw only when the z value is < 1.0

And don't forget to reset this mess after drawing the shadow quad...

Not sure about this anyway... Are OpenGL gurus here ? ;*)

Hope this helps.

Share this post


Link to post
Share on other sites
I assume you didn't forget to reset the depth range right after drawing the quad (glDepthRange(0.0, 1.0)).

Drawing caps is easy :
- render all triangles of your shadow casting object that don't "see" the light (i.e. light is in their "back") ;
- render all other faces displaced using the function you used to extend the shadow volume (i.e. translate all vertices 100 units away from the point light IIRC).

Share this post


Link to post
Share on other sites
Quote:
Original post by rodzilla
I assume you didn't forget to reset the depth range right after drawing the quad (glDepthRange(0.0, 1.0)).

Drawing caps is easy :
- render all triangles of your shadow casting object that don't "see" the light (i.e. light is in their "back") ;
- render all other faces displaced using the function you used to extend the shadow volume (i.e. translate all vertices 100 units away from the point light IIRC).


shouldn't it be

- render all faces of your shadow casting object that "see" the light (i.e. light is in their "front") ;
- render the same faces displaced using the function you used to extend the shadow volume (i.e. translate all vertices 100 units away from the point light IIRC) but with vertics in reverse order.

Share this post


Link to post
Share on other sites
lc_overlord: You're right ! I'm stupid. The method I describe will only work with some models (two manifold or something). But using back faces would make the shadow volume smaller (and thus save fill-rate) I think.

Share this post


Link to post
Share on other sites
if i render caps as lc_overlord said, the shadow volume disappears completly :/

i've done some attempts and i've discovered that if i change the order of the vertices of the volume nothing is rendered (this time without rendering caps) : assuming that for an edge k I have 2 verts a1 and a2 and the extruded verts are respectively e1 and e2, if i render a1,v1,v2,a2 it works, but if i render a2,v2,v1,a1, the volume disappears
o_O

Share this post


Link to post
Share on other sites
here's my demo with source.I took the basecode from codesampler.com
http://www.neoborn.com/users/b3rs3rk/shadow%20demo.rar

left click and drag the mouse to move the camera,F1 draws the volume and arrows keys move the shadow

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this