Shadow Capping

Hi!

I’ve read an article at Gamasutra about shadow volumes and they are offering a way to solve the problem which occurs when the camera is inside the volume. They are using a technique called ‘capping’. Does anyone know what this is and how it works? Are there any documents on capping?

Thanks in advance
LaBasX2

I think what they are talking about is taking the object that they are using to create the shadow volume from, and projecting it onto the front clip plane.

Then you can treat the camera as if it were actually OUTSIDE the shadow volume and render the projected polygon to the stencil buffer as if you are looking INTO the shadow volume. The effect of this is almost like you are molding the shadow volume around the part of the view frustum that extends from the viewpoint to the near clip plane.

The advantage of this technique is that you can treat everything the same. You are always “outside” of the shadow looking in, instead of handling inside one way and outside a different way. However, I think the greatest advantage of using this technique is that it covers the case where the shadow frustum instersects the near clip plane in the middle of the screen (ie: when the screen is partially in-partially out of the shadow volume)

[This message has been edited by LordKronos (edited 03-15-2001).]

Thanks for your reply.

What you suggest sounds really very interesting. Did I understand you correctly?
Your approach doesn’t need any shadow volumes. You just project the complete object that casts the shadow, onto the near clipping plane using the same algorithm you would use for projected shadows. Then you just render this polygon to the stencil buffer and you have the same effect as you had by using shadow volumes.

I don’t think that this is what they are talking about at Gamasutra. Your algorithm seems to be much better. Have you already tested if it really works? I think if it really works, that’s an ingenious approach for rendering shadows. I didn’t find a similar approach on the web.

No, the projection is done in addition to the normal shadow volume. Wherever the shadow volume intersects with the near clip plane, you have a sort-of opening, so the projection becomes a “cap” on the volume, closing it up.

Ok, now I think I understand what you mean. I tried to implement capping in my shadow volume render code, but at the moment it doesn’t work correctly. Here are the things I’m doing:

1.) I check if the camera is inside the volume by checking the camera’s position against every plane of the shadow volume.
If it is inside, then I continue with step 2 else I start with step 5.

2.) I get the equation of the near plane using the code from http://www.markmorley.com/opengl/frustumculling.html

3.)I create a projection matrix for the near plane using Mark Kilgard’s code for projected shadows.

4.)Now I draw all the polygons of the object which casts the shadow to the stencil buffer.

5.) After that I continue with the shadow volume code I would use if the camera were outside the volume.

Is the principe correct? The problem is that if I’m looking into the lightsource, all the screen is black and if I’ looking into the opposite direction, there isn’t any shadow at all. By the way, in step 4, do I have to increase the stencil buffer values?

Thanks

Im not completely clear on your steps. I see a few problems there, but let me try to make this as simple as possible.

First of all, you want to eliminate step 1. The problem here is that it becomes very tricky to do this (not to mention more processor intensive than need be). There are 3 cases where the inside/outside check fails to give correct results.
1)When the viewpoint is INSIDE the shadow volume, but the near clip plane of the view frustum is OUTSIDE the shadow volume.
2)The opposite of case 1.
3)When the near clip plane of the view frustum is part in-part out of the shadow volume, regardless of where the viewpoint is.

Assuming you know how to do shadow volumes, all you have to do is always render the shadow volumes as if you are OUTSIDE of it. Then you need to do that capping. Project the poly casting the shadow onto the near clip plane and have it INCREMENT the stencil value (ie: as if you are looking into the shadow). However, dont try do the stencil decrement on this cap.

A few things you need to be aware of when doing the cap.

  1. make sure the poly/object that you use to make the cap never overlaps (ie: the single cap should never increment any pixel more than once)
  2. You have to be careful that you dont “back project” the cap onto the near clip plane. The simplest way to do this is to get the plane equation of the poly you are projecting. If the light source and the camera are on the same side of this plane, dont bother with the cap (it is unnecessary, since there is no way you could possible be in the shadow). I should note, you may have a problem when the the camera and the object casting the shadow are all in VERY CLOSE proximity to each other. You could end up back at the case where the camera outside the volume but the near clip plane is inside.

All in all, I think you will find that the shadow volume (although it currently gives the best results) requires a bunch of hacks. Each hack gets a little closer to the desired results but still leaves a little possibility for error. I have yet to see an implementation of shadow volumes that is 100% foolproof (if you play with them enough, they always seem to have some small case where they confuse whats inside and whats outside of the shadow volume).

Thank you very much again for your help.

Somehow my capping algorithm doesn’t work correctly. I will try to find out what’s wrong.
Do you know if there is any code on capping the shadow volume on the net?

None that I’ve ever seen

Ok, I finally got this capping working more or less. Now it’s ok if you’re inside the shadow volume, but when you’re at the edge of the shadow volume, there are still sometimes errors with the near clipping plane. I think the article at Gamasutra even mentions that capping doesn’t solve the problem with the near plane.

Well, so my conclusion is that shadow volumes aren’t suitable for an engine where every brush casts shadows. There are just too many situations where errors could occur.
So what other alternatives do I have? I was playing with projected shadows. They’re working perfectly but they are pretty slow, especially when you have objects with many triangles.
Are there any other good working and fast methods of doing shadows?

Thanks

Hi!

Finally I got this capping working. Thank you very much again LordKronos for your help.

There is a new document uploaded at the NVidia page which shows a solution to the near clipping plane problem. So obviously I’m wrong with my conclusion about shadow volumes. Shadow volumes really seem to be an good way of calculating shadows.

Does anyone understand how Carmack’s reverse works, because I’ve tried it but just replacing

glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
by
glStencilOp(GL_KEEP, GL_DECR, GL_KEEP);

and replacing
glStencilOp(GL_KEEP, GL_KEEP, GL_DECR);
by
glStencilOp(GL_KEEP, GL_INCR, GL_KEEP);

doesn’t work.

Thanks in advance
LaBasX2