I had a question about shadow volumes largerly based on the recent post on the matter. The basic algorithm involves clearing the stencil for each light. And that makes sense, you need to do so, inorder for the shadow from each light to “accumulate” properly. I was thinking what if you don’t care about shadows accumulating properly. What if you wanted a pixel to be a constant shade regarless of how many shadow volumes it is contained within. Obviously the shadows won’t look as good but for the sake of argument is this correct. Can I draw all shadow volumes for all lights at once without clearing the stencil for each light? Technically as far as I can tell the stencil should inc/dec properly. Correct?
The values in the stencil buffer would be correct, but your resulting scene would not, because one light can kill the shadow of another.
Just take a box for example with 2 lights placed on 2 opposite sides. If you place all shadows immedialty, you can see that you won’t get proper illumination.
Thats a good point Gorg. Makes Sense. Thanks.
Still wish there was a way to avoid the clear. Clearing is such a slow pain in the ass.
You don’t need to clear. I don’t clear in my StencilShadow demo between each light. Instead you can just use glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO) when you draw your geometry.
“Fast clears” are available in most recent hardware and using them often helps with bandwidth saving schemes built in to the hardware. I expect that in the future it will always be more efficient to just make a clear call than to actively avoid them. Today, however, your mileage may vary – so try both ways.
With a very simple example Gorg finally gave me and example that leads to why you must clear the stencil everytime. Unless my mind is failing more than usual, it appears that the only time you would have to do this is when lights can “see” each other. Or perhaps more specifically whenever shadow volumes intersect each other. This is rather likely with omni lights. I figured that if you are using directional lights it may be possible to render shadow volumes of multiple directional lights. Assuming that they don’t interfere. But of course this is a non trivial solution. Is it just me or does everything result in a non trival problem?
(: Happy Coding.
I found that by using glStencilOp(GL_ZERO, GL_ZERO, GL_ZERO) I got a speedup of around 10-15% over doing a clear. I have very little overdraw though. I suppose that if you have more overdraw at some point it would be better to use a clear though.
OT: Wouldn’t btw the stencil buffer be very compressible, for doing something like the Zbuffer compression which is done by Radeons and GF3/4? I haven’t heard anything about stencil compression, but maybe it’s being done already? If you tile the stencilbuffer into say 8x8 blocks I suppose > 90% of the blocks would contain all pixels with the same stencil value. Would compress very good.
Another idea I had the other day, since I suppose many games from Doom3 and on will use stencil shadows I suppose it would be benefical for future hardware to instead of wasting silicon by throwing in say 8 fullblown pipelines which usually can’t be fed due to insufficient bandwidth anyway you could instead have 4 full pipelines and 4 (or more) el cheapo pipelines which can only do a subset of the operations, for instance do depth/stencil only. Could boost performance a lot in games using stencil shadows I suppose.
I’ll actually have to disagree somewhat with Cass’s advice; stencil clears are not free, certainly, and I wouldn’t suppose they will be in the future.
Actually, in many cases, you can do better to clear depth and stencil than to clear just stencil or just depth. (Then again, in other cases, that doesn’t hold.)
Rendering your scene with stencil ops ZERO can certainly be a win in many cases. If you render the scene once after each light source, that certainly is a decent way to reset things.
I can imagine a few circumstances in which a clear would end up being faster than that, although I don’t expect you to hit them.
This stuff can all get bizarre and unintuitive when the HW gets too smart. The most confusing part is, the HW keeps changing, so any advice I give you here today may not work in some cases, or on some cards.
For example, the question of whether clearing depth alone or depth and stencil together is faster, if you don’t need stencil cleared at that point in time, but your app uses stencil.
I can imagine cases where they are the same speed; where clearing just depth is faster; and where clearing both is faster.
I suggest you experiment, and for a demo it probably won’t matter. If it’s a real app, well, experiment on a lot of different cards.