Infinite shadow volumes V.S. finite length

What are the benefits from using infinite shadow volumes versus using a finite length of them.

I can clearly see culling effects between them… any thoughts ??

I’m not sure what you mean by culling effect (less pixels to draw?), but another thing would be that you don’t always want shadow produced by light source in one room have effect on the walls of neighbourous room.
This was described in a really good article on shadow volumes on

[This message has been edited by MickeyMouse (edited 01-16-2003).]

By all means, go for finite shadow volumes if you can. There’s no mystery, the fillrate cost is too high for infinite shadow volumes unless you restrict yourself to one, or two lights.

With finite shadow volumes (light has an attenuation radius of a few meters), you can get pretty decent performance. I’ve had a scene with 15k polys and 33 attenuated point lights, casting shadow volumes, running at 33 fps on my Radeon 8500. On the same system, i get the same framerate with only 2 infinite shadow volumes.

I’m guessing the performance Doom III achieves is only due to finite shadow volumes.


I noticed from studying Doom3 that carmack is doing a combination of a lot of tricks. He is using infinite projection, and also finite projection, but also projection onto a plane.
you should always scissor volumes anyway, then the fillrate requirements of infinite volumes are pretty equal to finite volumes.
Carmack is also using this mysterious beam tree to speed things up too…

Infinite volumes address the known problems with near/far plane clipping. You can decide on a per-volume basis which method you want to use, so if you know your volume isn’t going to be clipped anyway, use a finite one. Scissoring should definitely help. GL_NV_depth_clamp and GL_EXT_stencil_two_side are also helpful if they are available. The “mysterious beam tree” serves to merge shadow volumes, AFAIK (i.e. so you can throw away a volume that is completely inside another one).

– Tom

Infinite volumes using the zfail approach with scissor clipping is really the best way. The scissor clips what doesnt needed to be drawn, thus saving fill. So doing that will be the same as finite volumes. Then the zfail part will eliminate the near plane clipping problem. It’s just obviously the best way, unless you don’t scissor of course.


Infinite shadow volumes with scissoring is enough to get good performance. Currently, I only use that approach only. If you don’t use scissoring, you won’t get a good picture of the performance of using infinite volumes. However, scissoring will not save as much fill as finite volumes but it’s close. I would recommend using a mix of finite and infinite volumes with scissoring for both ( it’ll save fill for the light passes aswell ).

Beam trees are nice to have but that’s something that can be added late in the development.

Culling of shadows is independent on the actual technique used to render them. Finite or not, the culling is the same.

My question is based on some experiments i have done…


  1. If i use scissors its quite difficult to get a close box around affected geometry. Especially if a have a complex room or landscape which most times gives me a larger scissor box than the screen…

  2. If i have a point light and a room or landscape it is quite handy to use the fact that the distance between a moving occluding object and a light is proportional to the distance between the light and the shadow “hit” point on the surface (a plane parallell to the moving object) . this gives you the possibility to use the length of the shadow as k * distance between light and occluder.

  3. beam trees are hard to implement on non convex objects

  4. two sided stencil cannot be used to render on a stencil offset surface like a mirror etc.

Yes, the scissor box will for large lights cover the entire screen. Not much can be done about that. I’m not sure I understand nr.4. I have mirror surfaces too but I haven’t implemented shadowing for that case yet. Why would two-sided stancil testing be problematic for that ?

I use recursive mirrors and portals and then I must use shadow that doeas all the incr first and then the decr so I dont end up with a decr first and then an incr. That will destroy the base offset stencil value

Originally posted by ToolTech:
I use recursive mirrors and portals and then I must use shadow that doeas all the incr first and then the decr so I dont end up with a decr first and then an incr. That will destroy the base offset stencil value

<a href=;EXT_stencil_wrap&lt;/a&gt; anyone?

works like integer incrementation in c and about any other language…

simple said x == ++(–x) for ALL values of x

then, you can use any approach…

or else, please explain again, tooltech… i possibly got it wrong…

I might have missed something about the etension for double sided stencil test, but my feeling is that when i use the reversed carmack algo i might end up with a decr first and then an incr. Becuase I need to do the stencil where the value s >= Sref i must do all the incr first and then the decr. Can i specify the order in the double sided stencil extntension ??

I also beleive that I will not gain from using two sided stencil test because i think my volumes are just fill rate limited. i have no advanced vertex programs etc…

I see what you mean now. Maybe you could use INCR_WRAP and DECR_WRAP. I couldn’t find anything in the spec about whether front or back faces are processed first. However, you might be able to simply define front faces as being CW instead of CCW and then reverse the usage of the front/back tests ( just a quick idea, I haven’t really thought this through ).

Yes, please use INCR_WRAP and DECR_WRAP, that eliminates order dependence and saturation problems.

Two-sided stencil still saves because it keeps the fill hardware busy all the time.
If you get too many discarded triangles in a row (it happens), the rasterizer can run out of triangles to process.

Thanks -

An alternative to INCR_WRAP and DECR_WRAP is to clear stencil to 128 instead of 0.


I can not really see how the usage of INCR_WRAP would help me. Don’t I need the order dependance of incr and then decr to use two sided on a already existing stencil value ??