Pro OpenGL ES for iOS

(singke) #1

228 CHAPTER 7: Well-Rendered Miscellany^


This is done in three stages. The first pass is to render the image only with ambient light
so that the shaded parts of the scene can still be visible. Next is the pass that writes
only to the stencil buffer, and the final stage writes the normal image with full
illumination. However, only the nonstenciled pixels can be written to the illuminated
areas, while they’re blocked from writing to the shaded parts, leaving just the original
ambient pixels visible. In practice, this is a little more complicated.
Going back to the mysterious glStencilOp() function used in the reflectance exercise
earlier, we can now make use of those weird GL_INCR and GL_DECR operations. GL_INCR
can increase the count in a stencil pixel by one, and GL_DECR will reduce the count by
one, both operations triggered under certain conditions.
The term shadow volume comes from the following example: imagine it’s a foggy night.
You take a bright light such as one of your car’s headlights and shine it into the mist.
Now do some shadow puppetry in the beam. You’ll still see part of the beam going
around your poorly done shadow of the state of Iowa and wander off into the distance.
We’re not interested in that part. What we want is the darkened part of the beam, which
is the shadow that is cast by your hands. That is the shadow volume.
In your OpenGL scene, assume you have one light source and a few occluders. These
cast shadows upon anything behind them, be it a sphere, cone, or bust of Woodrow
Wilson. As you look from the side, you will see objects that are shaded and those that
are illuminated. Now draw a vector from any fragment, illuminated or not, to your
camera. If the fragment is illuminated, the vector must, by definition, travel through an
even number of walls of your shadow volumes: one when it goes into the shaded
volume and one when it comes out (of course, ignoring the special case for a vector on
the edge of a scene that might not have to pass through any shaded regions). For a
fragment inside one of the volumes, the vector will have to pass through an odd number
of walls; the single extra wall that makes it odd comes from its own volume of residence.
Got it? Wait, it gets better.
Now back to stencils. The shadow volumes are generated to look like any other
geometry but are drawn only to the stencil, making them invisible since the color buffers
are all switched off. The depth buffer is used so that the volume’s walls will be rendered
in the stencil only if it is closer than the real geometry. This trick lets the shadow trace
the profiles of arbitrary objects without having to do complicated and fussy calculations
of intersecting planes against spheres or Easter Island statues. It merely uses the depth
buffer to do pixel-by-pixel tests to decide where shadow ends. So, when the volume is
rendered to the stencil, each side of each ‘‘cone’’ of the shadow will affect the stencil in
a different way. The side facing us will increment the value in the stencil buffer by one,
while the other side will decrement it. So, any regions on the other side of the volume
that are illuminated will match a part of the stencil mask in which all of the pixels are set
to zero, because the vector must go through the same number of faces going in as
going out. Any part that is in shade will have a corresponding stencil value of one.
Got that? That is why shadow volumes were never chosen for the exercise.
Free download pdf