shadow volume question

I know this is probably non-sense but I’ve just read the general idea of the shadow volume algorithm(haven’t looked into the actual calculation of the volumes but it doesn’t matter right now) and I couldn’t help asking this.
So the original idea is to:

  1. render the ambient & emmsive ligth contribution
  2. determine shadowed areas
  3. rerender scene w/ all lighting contrib. for the parts which are not shadowed by occluders.
    This requires two passes.So why not:
  4. render the normal scene(all lights on)
  5. determine shadowed areas
  6. render a whole-screen rect w/ stencil testing enabled.This can be black or transpart with transparency(and color maybe?)depending on the ambient light of the scene.
    This will not look as good as the first method in case of just ambient light sources and even worse for emmisive light sources but it will be significantly cheaper and can be cleanly be implemented as a light version since they both use the same preprocessing.
    So what am I missing?

The shadow is the difference between the scene rendered with just ambient & emissive lighting and the scene rendered with all lights on. The scene rendered with ambient & emissive lights will be a lot darker since the ambient light contribution is always small.

  1. Render the Scene with ambient & emissiev lighting.
  2. Determine the shadow volume updating stencil where the shadow belongs.
  3. Render the scene with all lights on except in shadowed areas(stencil will held information about where the shadow belongs).

Hope this helps.

Yes this is the realistic approach but can’t we save a lot of pixel filling by just rendering the lit scene and blackening or darkening (by drawing a whole-screen semitransparetn or black quad with stencil teting enabled and only where the stencil value is non-zero.This is not realistic but a lot cheaper and the only situation I can think of where it will be very obvious(physically speaking) is in the case that you try to darken(by means of a translucent quad) the edge of a spotlight area.The spotlight boundary will still be visible but it shouldn’t be.Another possibility would be to modulate the translucency of the quad according to the stencil value.In this way you’ll have different shadow darkness depending on how many occluders contribute to the specific area.This isn’t realistic of course but it might look good.What do you think of all this?

It is not correct as you say, but it works. In fact, this is exactly how the NeHe shadow volume tutorial does things.

Well, I doubted I would be the first to think of such a simple thing but is the difference really worth a whole second pass of the geometry?I doubt that real(ambient light) shadows would make such a big difference.

It does make a larger difference if you use multiple lights and when using per pixel lighting effects like bumpmapping and pp-attenuation (the same bad effect that you have with the spotlight).
Multiple lights also mean a problem espacially when they are colored, cause the shadowed areas do have the color of the light.
The other thing is that with multiple lights and complex per pixel effects you already do multiple passes:
one for ambient + emissive + lightmaps.
then one for each bumpmapped attenuated and cubemap normalized light
The final one which modulates the object with the base texture + glossy and reflection mapping.
Maybe some other passes to add the specular lighting of all lightsources.

So you dont loose that much performance.

For simple situations the fullscreen rect is a faster solution (and was the one used in the beginning as far as i remember). But cards get faster and faster and for my spacegame a fullscreen rect could be a bigger speed hit then rendering geometry twice.


I, see…Although regarding that multiple colored lights part,the shadowed areas have the color of the ambient light,don’t they?Except if they’re lit by an other light but then they’re not shadowed.So this method would be useful only if you want to implement some overall cheap version of the gfx engine(including ligting and all) or if the engine isn’t sophisticated enough to justify the extra passes.

zen a particularly good article on stencil buffer shadows is at gamasutra…

However it talks about doing n+1 passes (where n is the number of lights).

Just read through it.Thanks anyway though.

If you have a single light, then you can render the scene, render the stencil into scene, and render a darkening quad.

However, once you have more than one light, this doesn’t work anymore, because some pieces are only in shadow based on light 0 or based on light 1, and some pieces are in shadow from both of them.

Also, you typically want to render all diffuse light into RGB and all specular into A (if you use single-color specular lights) and then modulate the base color map in at the end. Else you have to read and modulate the base color map for each light addition pass.

It anyway doesn’t work. Applying a dark quad darkens by a fixed amount everywhere whereas the light’s contribution will vary accoring to the many factors that make lighting different to solid colour. I know I’m just stating the obvious, did I skip read the thread too quickly?

I haven’t thought about multiple lights but since the outcome of each pass would be the same I supposed it would work although it still would require more than one passes.
Madoc: it was considered as a cheap lower quality version in the first place.