Problem: In my application, volume shadows are going through walls.
What I want to do is render shadows for objects inside a geometry (building/mine) using multiple light sources. I don’t want the geometry to cast shadows.
Example: Two large halls, connected by a hallway, each with one or more light sources. Now the shadows of objects in hall one appear on the walls of hall 2.
What do I have to do do prevent object shadows from going through walls?
Is there a way to make the walls cast shadows only to setup the stencil buffer in a way to prevent object shadows from affecting the stencil buffer if there is already a wall shadow? How?
Pass 1: Render everything (bright)
Pass 2: Render object shadows (->stencil)
Pass 3: Render black quad (darkens all pixels with stencil != 0)
Alternative method:
Pass 1: Render everything (dark)
Pass 2: Render object shadows (->stencil)
Pass 3: Render everything again (brightens all pixels with stencil == 0)
For both paths shadows penetrate walls.
Here is a little image. Actually the shadow’s side walls consist of polygons extending to infinity. So the shadow faces for the object go through room 1 and are in front of that rooms rear wall.
There must be another way to prevent this. I would need to have that wall from room 2 cast a shadow too, but not render it, only use it to blot out the object’s shadow from the stencil buffer. Unfortunately, that doesn’t seem to work for multiple light sources and shadows.
you could as well have said nothing, because what you said doesn’t give me the faintest idea what I have to do. I need some detailled explanation, because I am obviously too dumb to figure it myself.
I wonder if you haven’t taken much time to really understand my entire setup and resulting problems.
I have changed the above picture: There is now a 2nd object, and the shadow for wall #1. If I render the entire mine, creating shadows for the walls too, that shadow will darken room #1 although it shouldn’t (because it has a light). It will also blot out the shadow of the 2nd object.
You need to do a stencil and light pass for each light source. Otherwise an area that is in shadow for one light source will always be completely dark, regardless of how many other light sources there are that should affect the surface.
You cannot simply combine shadow volumes from different light sources.
You ran into the same problem many people have encountered before: The moment you calculate shadows for some objects, you need to do so for all objects in you scene, including your static geometry. Else the shadows will seem to go through walls.
Everything that your lightsource touches also needs to cast shadows. That’s how Doom 3 works, too. That’s why many games still have shadows that suck (ie. Valve’s Source-Engine), because it’s pretty difficult to get good shadows, when you don’t calculate them for all objects equally (ie. only for dynamic objects).
Sorry, can’t tell you HOW to solve the problem, you need to find a solution that fits into your engine.
I didn’t say that the Source-Engine sucks. I said their dynamic shadows suck. That’s a BIG difference. In most other aspects the Source-Engine is pretty cool, in my opinion.
It’s not so easy to give you a detailed description, since it depends on how you integrate dynamic lighting and shadowing into your engine.
Technically it’s the most straight forward thing to use dynamic lighting and shadowing for everything and don’t have any precalculated lighting, at all. That’s what Doom 3 does and that’s what’s most processing intensive.
If you can live with that, then what you mentioned above is the correct way to do it.
However, many people don’t want it that way for several reasons, ie. performance or quality of the lighting (only hard shadows, the general look will be dark).
Therefore either you take the “easy” path (which can still be very difficult with stencil-shadows, since they are tricky to always get right) or you have to try out what tricks might be possible with your engine to reduce the issue. For example if you use a sector-based engine it might be possible for you to restrict the shadow-volumes to the sector that the object resides in, thus the shadows will only appear inside the sector the object is in. But that’s only ONE trick, as i already said, this is an issue for which there is no real solution.
I am having 50+ light sources per scene.
I can’t imagine that rendering a scene 101 times (for shadow volumes) to ever be faster than rendering it 51 times (for shadow mapping).
I don’t get your calculation Korval. Don’t you need for shadow mapping
1 pass for ambient
n passes for rendering the scene into the shadow-map
n passes to add light to the scene per lightsource
too?
Additionally, for shadow-mapping you might need more than one pass to create the shadow-maps, depending on the used technique (and some other factors).