stencil volume shadows

hi,

Im trying to implement shadowvolume rendering for
multiple objects, but I dont really see the light yet.
Here's a picture of the result, the code is below.
The even and odd parts in the stencil seem to be
cancelling out but I fail to see how that is.
http://www.xs4all.nl/~vdspek/shadowvolumes.jpg
The lower bunch of spheres only show the volumes.
The volumes are capped on both sides and the quads
that make up their surfaces have ccw winding, seen from outside.

Im using the algorithm from shadowvol.c at the opengl site:
http://www.opengl.org/developers/code/glut_examples/advanced/advanced.html
which utilises the 'carmack method', see:
http://developer.nvidia.com/docs/IO/2585/ATT/CarmackOnShadowVolumes.txt
and also implemented the slightly different nvidia method,
with the same result. Could anyone shed some light on this ?
Im really in the dark here  :-D

thanks,

Jonathan

----------------------------------------------------------------------

    glClear( GL_COLOR_BUFFER_BIT | \
                 GL_DEPTH_BUFFER_BIT | \
                 GL_STENCIL_BUFFER_BIT );

    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);
    glEnable( GL_DEPTH_TEST );
    glColorMask(GL_FALSE, GL_FALSE, \
                         GL_FALSE, GL_FALSE);
    glDepthMask(GL_TRUE);

    // only depth
    DrawSpheres( );

    glEnable(GL_STENCIL_TEST);
    glDepthMask(GL_FALSE);

    glStencilFunc(GL_ALWAYS, 0, 0);
    glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
    glCullFace(GL_BACK);  // increment using front face of shadow volume

    DrawVolumes();

    // m�thode Carmaque: decrement for clipped faces
    glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
    glCullFace(GL_FRONT);  // decrement using back face of shadow volume

    DrawVolumes();

    glDepthMask(GL_TRUE);
    glDepthFunc(GL_LEQUAL);
    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    glCullFace(GL_BACK);
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
    glStencilFunc(GL_EQUAL, 1, 1);  // draw shadowed part
    glDisable(GL_LIGHTING);

    DrawSpheres();

    glStencilFunc(GL_EQUAL, 0, 1);  // draw lit part //
    glEnable(GL_LIGHTING);

    DrawSpheres();


-------------------------------------------------------------
  please tear the sticker off my eddress before use
-------------------------------------------------------------


0
j
6/23/2003 6:05:20 PM
comp.graphics.api.opengl 7072 articles. 1 followers. Post Follow

2 Replies
668 Views

Similar Articles

[PageSpeed] 38

When you render concave object(s) OR multiple convex objects, you may have
multiple overlapping shadows for the same pixel, resulting in a stencil buffer
value greater than 1.

Then for correcting your problem, for the shadowing part you should not test
if STENCIL==1, you should test if STENCIL!=0 and that should do the trick.
That is, replace :
glStencilFunc(GL_EQUAL, 1, 1);  // draw shadowed part
with :
glStencilFunc(GL_NOTEQUAL, 0, (GLuint)(-1));  // draw shadowed part
and replace :
glStencilFunc(GL_EQUAL, 0, 1);  // draw lit part
with :
glStencilFunc(GL_EQUAL, 0, (GLuint)(-1));  // draw lit part

Just in case you don't know what (GLuint)(-1) is, it's a simple way of setting
all bits of the mask to 1, just like (GLuint)(0) would reset all bits of the
mask to 0.

Note that with this technique you're still limited to the number of bits in
the stencil buffer. For instance, with 8-bit stencil buffer the number of
overlapping shadows is limited to 255 per pixel (generally that limit is
enough hopefully).

Vincent


j wrote:

> hi,
>
> Im trying to implement shadowvolume rendering for
> multiple objects, but I dont really see the light yet.
> Here's a picture of the result, the code is below.
> The even and odd parts in the stencil seem to be
> cancelling out but I fail to see how that is.
> http://www.xs4all.nl/~vdspek/shadowvolumes.jpg
> The lower bunch of spheres only show the volumes.
> The volumes are capped on both sides and the quads
> that make up their surfaces have ccw winding, seen from outside.
>
> Im using the algorithm from shadowvol.c at the opengl site:
> http://www.opengl.org/developers/code/glut_examples/advanced/advanced.html
> which utilises the 'carmack method', see:
> http://developer.nvidia.com/docs/IO/2585/ATT/CarmackOnShadowVolumes.txt
> and also implemented the slightly different nvidia method,
> with the same result. Could anyone shed some light on this ?
> Im really in the dark here  :-D
>
> thanks,
>
> Jonathan
>
> ----------------------------------------------------------------------
>
>     glClear( GL_COLOR_BUFFER_BIT | \
>                  GL_DEPTH_BUFFER_BIT | \
>                  GL_STENCIL_BUFFER_BIT );
>
>     glEnable(GL_CULL_FACE);
>     glCullFace(GL_BACK);
>     glEnable( GL_DEPTH_TEST );
>     glColorMask(GL_FALSE, GL_FALSE, \
>                          GL_FALSE, GL_FALSE);
>     glDepthMask(GL_TRUE);
>
>     // only depth
>     DrawSpheres( );
>
>     glEnable(GL_STENCIL_TEST);
>     glDepthMask(GL_FALSE);
>
>     glStencilFunc(GL_ALWAYS, 0, 0);
>     glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
>     glCullFace(GL_BACK);  // increment using front face of shadow volume
>
>     DrawVolumes();
>
>     // m�thode Carmaque: decrement for clipped faces
>     glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
>     glCullFace(GL_FRONT);  // decrement using back face of shadow volume
>
>     DrawVolumes();
>
>     glDepthMask(GL_TRUE);
>     glDepthFunc(GL_LEQUAL);
>     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
>     glCullFace(GL_BACK);
>     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
>     glStencilFunc(GL_EQUAL, 1, 1);  // draw shadowed part
>     glDisable(GL_LIGHTING);
>
>     DrawSpheres();
>
>     glStencilFunc(GL_EQUAL, 0, 1);  // draw lit part //
>     glEnable(GL_LIGHTING);
>
>     DrawSpheres();
>
> -------------------------------------------------------------
>   please tear the sticker off my eddress before use
> -------------------------------------------------------------

0
Vincent
6/24/2003 11:08:11 AM
thanks, that did it


--
-------------------------------------------------------------
  please tear the sticker off my eddress before use
-------------------------------------------------------------
"Vincent DAVID" <vincentdavid@c-s.fr> wrote in message
news:3EF8311B.DF5157F4@c-s.fr...
> When you render concave object(s) OR multiple convex objects, you may have
> multiple overlapping shadows for the same pixel, resulting in a stencil
buffer
> value greater than 1.
>
> Then for correcting your problem, for the shadowing part you should not
test
> if STENCIL==1, you should test if STENCIL!=0 and that should do the trick.
> That is, replace :
> glStencilFunc(GL_EQUAL, 1, 1);  // draw shadowed part
> with :
> glStencilFunc(GL_NOTEQUAL, 0, (GLuint)(-1));  // draw shadowed part
> and replace :
> glStencilFunc(GL_EQUAL, 0, 1);  // draw lit part
> with :
> glStencilFunc(GL_EQUAL, 0, (GLuint)(-1));  // draw lit part
>
> Just in case you don't know what (GLuint)(-1) is, it's a simple way of
setting
> all bits of the mask to 1, just like (GLuint)(0) would reset all bits of
the
> mask to 0.
>
> Note that with this technique you're still limited to the number of bits
in
> the stencil buffer. For instance, with 8-bit stencil buffer the number of
> overlapping shadows is limited to 255 per pixel (generally that limit is
> enough hopefully).
>
> Vincent
>
>
> j wrote:
>
> > hi,
> >
> > Im trying to implement shadowvolume rendering for
> > multiple objects, but I dont really see the light yet.
> > Here's a picture of the result, the code is below.
> > The even and odd parts in the stencil seem to be
> > cancelling out but I fail to see how that is.
> > http://www.xs4all.nl/~vdspek/shadowvolumes.jpg
> > The lower bunch of spheres only show the volumes.
> > The volumes are capped on both sides and the quads
> > that make up their surfaces have ccw winding, seen from outside.
> >
> > Im using the algorithm from shadowvol.c at the opengl site:
> >
http://www.opengl.org/developers/code/glut_examples/advanced/advanced.html
> > which utilises the 'carmack method', see:
> > http://developer.nvidia.com/docs/IO/2585/ATT/CarmackOnShadowVolumes.txt
> > and also implemented the slightly different nvidia method,
> > with the same result. Could anyone shed some light on this ?
> > Im really in the dark here  :-D
> >
> > thanks,
> >
> > Jonathan
> >
> > ----------------------------------------------------------------------
> >
> >     glClear( GL_COLOR_BUFFER_BIT | \
> >                  GL_DEPTH_BUFFER_BIT | \
> >                  GL_STENCIL_BUFFER_BIT );
> >
> >     glEnable(GL_CULL_FACE);
> >     glCullFace(GL_BACK);
> >     glEnable( GL_DEPTH_TEST );
> >     glColorMask(GL_FALSE, GL_FALSE, \
> >                          GL_FALSE, GL_FALSE);
> >     glDepthMask(GL_TRUE);
> >
> >     // only depth
> >     DrawSpheres( );
> >
> >     glEnable(GL_STENCIL_TEST);
> >     glDepthMask(GL_FALSE);
> >
> >     glStencilFunc(GL_ALWAYS, 0, 0);
> >     glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
> >     glCullFace(GL_BACK);  // increment using front face of shadow volume
> >
> >     DrawVolumes();
> >
> >     // m�thode Carmaque: decrement for clipped faces
> >     glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
> >     glCullFace(GL_FRONT);  // decrement using back face of shadow volume
> >
> >     DrawVolumes();
> >
> >     glDepthMask(GL_TRUE);
> >     glDepthFunc(GL_LEQUAL);
> >     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
> >     glCullFace(GL_BACK);
> >     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
> >     glStencilFunc(GL_EQUAL, 1, 1);  // draw shadowed part
> >     glDisable(GL_LIGHTING);
> >
> >     DrawSpheres();
> >
> >     glStencilFunc(GL_EQUAL, 0, 1);  // draw lit part //
> >     glEnable(GL_LIGHTING);
> >
> >     DrawSpheres();
> >
> > -------------------------------------------------------------
> >   please tear the sticker off my eddress before use
> > -------------------------------------------------------------
>


0
j
6/24/2003 12:23:19 PM
Reply: