stencil buffer shadowing

Started by
8 comments, last by hints 21 years, 8 months ago
I am trying to understand this... /* here is what I found at nvidia.com/developer */ glDepthMask(0); glColorMask(0,0,0,0); glEnable(GL_CULL_FACE); glEnable(GL_STENCIL_TEST); glStencilMask(~0); glStencilFunc(GL_ALWAYS, 0, ~0); // Increment for back faces glCullFace(GL_BACK); glStencilOp(GL_KEEP, // stencil test fail GL_INCR, // depth test fail GL_INCR); // depth test pass renderShadowVolumePolygons(); // Decrement for front faces glCullFace(GL_FRONT); glStencilOp(GL_KEEP, // stencil test fail GL_DECR, // depth test fail GL_KEEP); // depth test pass renderShadowVolumePolygons(); /*** end of code ****/ here is what I think. Say you have a screen with a square in it (counter-clockwise, i.e. facing you )
  
|-----------------|
|                 |
|    ---------|   |  <--- light coming from this direction
|    | square |   |  (north-east of the screen, in an angle)
|    ----------   |
|                 |
|-----------------|

with the light, you are expecting a shadow like this...

S: shadow

|-----------------|     -- light coming from this direction
|                 |   <-|
|      --------|  |
| ----| square |  |
| | S  --------|  |
| |----|          |
|-----------------|

after the first pass of the code this is the stencil buffer


glCullFace(GL_BACK);
glStencilOp(GL_KEEP,   // stencil test fail

                    GL_INCR,   // depth test fail

                    GL_INCR);  // depth test pass

renderShadowVolumePolygons();


after we rendered the square
(stencil buffer initial had zeros)

|-----------------|     -- light coming from this direction
|    0            |   <-|
|      --------|  |
| ----|   1    |  |
| | 0  --------|  |
| |----|    0     |
|-----------------|


after we rendered the light

(the light passes the z-buffer on the square, so we incriment it
and the light fails the z-buffer on the shadow region, so we increment it as well)

S: shadow

|-----------------|     -- light coming from this direction
|    0            |   <-|
|      --------|  |
| ----|   2    |  |
| | 1  --------|  |
| |----|    0     |
|-----------------|


after the second pass, this is the stencil buffer

// Decrement for front faces

glCullFace(GL_FRONT);
glStencilOp(GL_KEEP,   // stencil test fail

                    GL_DECR,   // depth test fail

                    GL_KEEP);  // depth test pass

renderShadowVolumePolygons();


S: shadow

(again, only the shadow region fails the test, the square value is kept)

|-----------------|     -- light coming from this direction
|    0            |   <-|
|      --------|  |
| ----|   2    |  |
| | 0  --------|  |
| |----|    0     |
|-----------------|

  
now...obviously this is wrong (hehe). Since we are getting the square back, not the shadow. Can someone tell me which part was wrong? (possibly the light?) please excuse my bad ascii drawings.... [edited by - hints on August 11, 2002 10:07:54 PM]
Advertisement
maybe this should be in the "Graphics Programming and Theory
" forum?
>glStencilOp(GL_KEEP, // stencil test fail
>GL_INCR, // depth test fail
>GL_INCR); // depth test pass
pass and fail also increase ?!
From OpenGL Game Programming:

Pass 1: Render the scene using ambient and emissive lighting
Pass 2: Render shadow volumes with color and depth buffer drawing disabled, backface culling enabled, and the stencil buffer set to increase.
Pass 3: Render shadow volumes with color and depth buffer drawing disabled, frontface culling enabled, and the stencil buffer set to decrease.
Pass 4: Render the scene using specular and diffuse lighting, draw only where the stencil buffer is zero.
~neoztar "Any lock can be picked with a big enough hammer"my website | opengl extensions | try here firstguru of the week | msdn library | c++ faq lite
If you don''t understand it after a minute of looking, then it''s above your level. Start simpler.

Helpful links:
How To Ask Questions The Smart Way | Google can help with your question | Search MSDN for help with standard C or Windows functions
quote:Original post by siaspete
If you don''t understand it after a minute of looking, then it''s above your level. Start simpler.


No, never give up!!!
Sit down and find more sources and think as long as you understand
quote:Original post by neoztar
From OpenGL Game Programming:

Pass 1: Render the scene using ambient and emissive lighting
Pass 2: Render shadow volumes with color and depth buffer drawing disabled, backface culling enabled, and the stencil buffer set to increase.
Pass 3: Render shadow volumes with color and depth buffer drawing disabled, frontface culling enabled, and the stencil buffer set to decrease.
Pass 4: Render the scene using specular and diffuse lighting, draw only where the stencil buffer is zero.


hmmm...I found this over flipcode (not to say gamedev.com isnt great )

"Stencil Buffer Shadowing
Each light source renders the scene as seen from it''s own position, and fills a z-buffer. Then the scene is rendered from the viewpoint of the camera. During this stage, the 3D position for each pixel that is about to be drawn is projected onto the generated stencil buffers to determine whether the pixel is behind another pixel from the viewpoint of the light source. This technique is fast for a single lightsource, since the scene can be rendered from the viewpoint of the lightsource using only z-buffer filling. For multiple lightsources, memory requirements increase quickly. Stencil buffers are only supported by some of the currently available hardware accelerators. On the other accelerators, this technique is impossible. Finally, the shadows produced this way tend to look blocky, because of the resolution of the stencil buffer."

I think the problem is that I did not know you render the light from the light''s point of view.

For example...


  You are the light, and you are looking at the Sphere (I know it doesnt look like one..).|--------------------||                    ||     --------|      ||     |SPHERE |      ||     |------ |      ||                    ||--------------------|The part that is covered up by the sphere is the shadow (since you are the light)|--------------------||                    |  |     --------|      ||     |sphere |<--(shadow is under here)|     |------ |      ||                    ||--------------------|1st pass, render the front face +1 (still from the light''s perspective)|--------------------||           1        |  |     --------|      ||     | 1     |      ||     |------ |      ||                    ||--------------------|2nd pass, render back face, with stencil -1|--------------------||           1        |  |     --------|      ||     | 0     |      ||     |------ |      ||                    ||--------------------|you are done. Render black (gray...whatever), where stencil == 0. That is your shadow  


Am I getting it right this time???
quote:Original post by stefu
No, never give up!!!
Sit down and find more sources and think as long as you understand


I don''t mean give up. I mean start on something that is at his level, then move on to harder material step by step.

He''s only going to get stuck and post questions about things he should know already if he doesn''t.

Helpful links:
How To Ask Questions The Smart Way | Google can help with your question | Search MSDN for help with standard C or Windows functions
** DISCLAIMER: I'VE BEEN RESEARCHING REALTIME SHADOWS FOR ONLY A FEW DAYS NOW, SO DON'T TAKE ANYTHING I SAY AS THE TRUTH **

quote:Original post by hints
"Stencil Buffer Shadowing
Each light source renders the scene as seen from it's own position, and fills a z-buffer. Then the scene is rendered from the viewpoint of the camera. During this stage, the 3D position for each pixel that is about to be drawn is projected onto the generated stencil buffers to determine whether the pixel is behind another pixel from the viewpoint of the light source. This technique is fast for a single lightsource, since the scene can be rendered from the viewpoint of the lightsource using only z-buffer filling. For multiple lightsources, memory requirements increase quickly. Stencil buffers are only supported by some of the currently available hardware accelerators. On the other accelerators, this technique is impossible. Finally, the shadows produced this way tend to look blocky, because of the resolution of the stencil buffer."

I think the problem is that I did not know you render the light from the light's point of view.

That's a different technique then the code you originally posted.

Have you read the Intel article on shadow volumes? Cause that's the technique your code seems to use. It's pretty good, i understood the theory behind it on the first read,....

Good luck.

-Crawl

[edited by - Crawl on August 14, 2002 6:36:52 AM]
--------<a href="http://www.icarusindie.com/rpc>Reverse Pop Culture
hmmm...I found this article at nehe.gamedev.com

http://nehe.gamedev.net/tutorials/lesson.asp?l=27

If it is the same technique,I "think* I finally understand now. You have to manually draw the shadow volumes.

Since you are drawing the shadow volumn in the same orientation each time, thus your shadow volume in the front are CCW, whereas your shadow volumes in the back are CW.

You first render in front facing orientation. Your front shadow volume will map to the stencil buffer (set a mark etc..). Then you render in back facing orientation. Your back shadow volume will then cancel some unwanted shadow. like this:



          |---------------------|        |      ------- Plane  |        |       |   | <--back shadow volume front shadow-> |   |         |        |       | /           |        |       |/    <-- shadow casting object EYE    |                     |    ( a plane at 45 degree)        |---------------------|                LIGHTEYE VIEW:        shadow on the plane   |------------------|   |  |------|        |   |  | -----------|  |   |  | |          |  | front shadow volume   |  | -----------|  |   |  |------|        |   |------------------|        shadow on the plane   |------------------|   |  |------|        |   |  |   ---------|  |   |  |   |        |  | back shadow volume   |  |   ---------|  |   |  |------|        |   |------------------|   front minus back shadow volume == shadow projection        shadow on the plane   |------------------|   |  |--------|      |   |  | |---|  |      |   |  | |   |  |      | back shadow volume   |  | ----|  |      |   |  |--------|      |   |------------------|  


This algorithm need to walk through every vertice to create a shadow volumn. It seems that it is not reasonable for large polygons model (5000+?). With dynamically lightings, it isnt possible to generate shadow volumes before runtime. Maybe I am still missing some important points?

This topic is closed to new replies.

Advertisement