I was wondering if someone could suggest why I am getting self shadowing in this particular instance. I compute my depth map with a projection PM and bind it as a depth texture. I set my texture matrix to be PM and render the scene again. The problem is that I’m getting self shadowing on the surface, which I find puzzling because I 1) set my depth texture precision to the same as my z-buffer, and 2) am rendering into a pixelbuffer with texture dimensions (so there’s no aliasing in UV).

Why I am getting self-shadowing in this instance? Any ideas? (I know there are ways of fixing this problem, but I am just perplexed at why this problem exists in the first place.)

You’re rendering the scene from two different points of view. Because depth precision is finite, both views will require depth values to be rounded off to the nearest representable value. Therefore, since both your shadow map and the Z-buffer contain approximate values rather than exact ones, the depth comparison itself is also not exact – hence the artefacts you’re seeing.

Typically, this is solved by rendering the back facing polygons (counting from the light) into the shadow buffer. That way, there will be aliasing with the front facers only where the geometry is very thin.

You’re rendering the scene from two different points of view.

but I’m not. I understand the precision issue, but the same matrix that generates the depth buffer in the first place is the texgen matrix used to project texture coordinates and compare R against the depth buffer. I guess I didn’t make it as clear as I could have, but when I said PM in my original post for both matricies, i meant the SAME PM, not PM for one and P’M’ for the second.

Because depth precision is finite, both views will require depth values to be rounded off to the nearest representable value. Therefore, since both your shadow map and the Z-buffer contain approximate values rather than exact ones, the depth comparison itself is also not exact – hence the artefacts you’re seeing.

… which I agree with, but surely i’d get the same rounding errors from the same projection/modelview and texture generation matrix. My question is essentially “what majic is going on that gives me different precision”?

Typically, this is solved by rendering the back facing polygons (counting from the light) into the shadow buffer. That way, there will be aliasing with the front facers only where the geometry is very thin.

that, sir, is a bloody brilliant idea. except… no, I can change that. <muses> thanks.

… except, I can’t change it after all. I seriously need to render front facing polygons rather than backfacing polygons because… well, the back facing technique will light more surface elements than I want it to.

for instance, if I had cube with the bottom plane perfectly aligned with the camera’s x axis and principal point, like so:

+----+
A C
| |
+-B--+ > (camera)

then… well, its a border line case, I guess, but face B isn’t being rendered and so the depth seen through the projection of B is actually the depth of A (which IS rendered). … but this means that all of B is considered lit. This is not good. I need the front face (C) rendered to B is considered in shadow.

… which still means I need to sort out this precision problem, and I am still perplex why there IS this precision problem for this case when projection and texture gen matricies are identical.

Whether or not it’s the same matrix doesn’t matter.

First, you render the scene from the point of view of the light. This results in a bunch of depth values which are rounded off to the nearest representable value (typically 24-bit). Next, you render the scene from the point of view of the camera, and you use TexGen with the same matrix as before to generate new depth values. Again, these values have to be rounded off to the nearest representable value, although now they’re texcoords so presumably they’re 32-bit. You’re comparing two approximate values with different precisions, so the comparison cannot be accurate.

Let’s take an example. Suppose that for some fragment being shaded, the TexGen’ed depth is exactly 123.30 cm and the shadow map depth is exactly 123.45 cm. Hence, the fragment is supposed to be shadowed.

Now let’s say that your 24-bit depth map is accurate to 1 cm and your 32-bit TexGen’ed depth values are accurate to 5 mm (I know that doesn’t make any sense, but it’s just for the sake of this example). The TexGen’ed depth will be rounded off to 123.50 cm, whereas the shadow map depth will be rounded off to 123.00 cm, which means the fragment ends up being lit.

Also, about the backface thing… I assume you really meant a situation like this?

+----+
A C
| |
+-B--+ * (light)

V (camera)

Even though you’re right that B won’t be shadowed by the shadow map comparison, it won’t appear as lit either, because the surface is perpendicular to the light. This means your (N.L) dot product will be zero, so the surface will appear black even if it is not considered to be in shadow.

– Tom

(Edit: UBB code)

[This message has been edited by Tom Nuydens (edited 09-23-2003).]

the texture precision is a potential problem, I guess. I am using my texture with the same precision as the depth buffer, but I guess its possible the comparison is done in registers in higher precision. I was kinda hoping it wasn’t. :-/

I’m not actually doing shadow mapping at all, so I need to still process the B quad irrespective of its orientation to the camera, so I still care that it is considered lit. It is very important that it isn’t.

THanks for the heads up on the register precision, though. I guess i will have to go and uncomment out the code to push my depth buffer back a notch.

I’m not actually doing shadow mapping at all, so I need to still process the B quad irrespective of its orientation to the camera, so I still care that it is considered lit. It is very important that it isn’t.

It doesn’t have to be. As long as your lighting is done via dot(N,L), you will get the right effect. Does it matter that the shadow map says it’s lit, but the eventual lighting computations say that it is not? After all, the shadow map doesn’t have to tell you that objects oriented away from the light are unlit; the lighting computation should tell you that.