Shadow Mapping and PolygonOffset

I have never seen a paper or presentation on how to choose a polygon offset when doing shadow mapping.

It seems like there should be a better way than just adjusting it until it looks good.

Originally posted by Nakoruru:
It seems like there should be a better way than just adjusting it until it looks good.

Apparently that’s what Pixar have to do

It must be luxurious to know exactly where all your objects and lights are going to be :slight_smile:

I said I had never read a presentation which covered this, but actually the shadow mapping presentation from nVidia does give some insight into the error range and absolute error that is possible. I just didn’t pay much attention to it because before now there was no way to really use it because it involved derivatives in screen space.

Maybe one could use the ddy and ddx functions to calculate a polygon offset per pixel in a fragment program, instead of using a constant one for the whole scene. It would increase the offset in areas likely to have precision problems.

Polygon offset already does this. That’s why there are two parameters. One is a constant offset the other is a multiplier for derivative of z (measured in units per pixel span).

[This message has been edited by dorbie (edited 10-14-2002).]

The RedBook shows the equation used in that function and also tells you how to choose the best values depending on what you are doing or want.

-SirKnight

I figured all this out after I actually started playing with it. The problem I have now is that polygon offset uses an implementation dependent value which is guaranteed to make a difference (for the unit parameter). I am wondering if it is possible to determine such a value for variable in a fragment program.

In other words, is there a way to bump a floating point number and guarantee that it will actually be incremented. Perhaps such a function is needed in glslang or Cg (if it does not already exist).

Actually, dorbie, ‘already does that’ implies that all I wanted to do was implement PolygonOffset in a fragment program. But, I also wanted to find a way to determine which parameters would be best for PolygonOffset --without guessing–, and do that per-pixel if possible. This is because I doubt there is a single good value you can set for an entire scene, and I hate the idea that shadow maps require tweaking.

one thing that stops tweaking is don’t use a simple comparison, but a smooth curve…

instead of if(length(light - point) > shadowmap[point]) shadowed() else unShadowed(), do a lerp between some range. the range can be determined by the distance to the light, as you can calculate how big the smallest stepsize on the depthmap there is. or you can use even more values to estimate that bether…

but that could kill the artefacts (including some offset of course) quite much, as it would blur them. no thin lines, but some tinywinyshading…

It already does this. You don’t need to know the value. It does exactly what you need. Not for offsetting in some fragment program but for offsetting for the purpose of artifact ‘free’ depth map shadows.

When rendering the depth map offset by the values guaranteed to displace away from the viewer to avoid self occlusion.

This is exactly what is required for perfect depth buffer offset, even with a low resolution depth map and imprecise depth buffer.

The only possible issue is that implementations have been attrocious at correctly assessing glPolygonOffset, thanks in part to complicity of ARB members deliberately not enforcing a useful quality test because they know they’d fail it.

[This message has been edited by dorbie (edited 10-14-2002).]

“It already does this…”

I know.

Now, lets proceed with the assumption that I am trying to do something for which PolygonOffset cannot be used for whatever reason. For instance, I want to offset something which is not the Z depth value, or a value which I have calculated myself. That is what I was talking about.

I was just saying it would be nice to have a function which incremented or decremented a value by the smallest quantum. This is because foo++ or foo-- on a floating point value is not always guaranteed to actually change the value (at least in C, maybe it will in glslang or Cg).

daveperman,

I tried to use the smoothstep function, but for some reason it did not help at all. All the shadow acne was still present, it was just smoother :slight_smile:

It boggles my mind as to why I could not get it to work. Maybe I made a mistake. Have you tried it yourself? If so then what did your code look like?

EDIT: Dorbie, are you saying that PolygonOffset work perfectly, but that it doesn’t because no body is actually complying with the standards? If so, then what values should be passed to PolygonOffset to make it work perectly for shadow maps?

[This message has been edited by Nakoruru (edited 10-15-2002).]

pocketmoon,

I think that Pixar user needn’t to adjust this all time : it might been a generic solution because under Maya, you needn’t adjust the offset. The option is present, but I never use it. In this type of rendering engine (Maya, Renderman, Mentalray…), some advanced filtering processing are applied to smooth, blend and discare all bias problems : such filterings are not avaible on actual chips.

Gaby

Originally posted by Nakoruru:
[b]I tried to use the smoothstep function, but for some reason it did not help at all. All the shadow acne was still present, it was just smoother :slight_smile:

It boggles my mind as to why I could not get it to work. Maybe I made a mistake. Have you tried it yourself? If so then what did your code look like?[/b]

have you ever seen something from me? i’m a brainy, but i’m terrible bad in some topics to implement that stuff (basically matrices, and they are, uhm, quite important for shadowmapping to get it to work )

no, i never did it, but i worked with the nvidia shadowing demo, the one with emulated 16bit shadowing and all that fancy thing. and i know like that the artefacts that occur…

basically i suggest to bias them as before, by some constant value (wich should be determinable. somehow. and thats what the topic is about… ), and then use the smoothstep (very smooth ) to filter away the resting possible artefacts (even while there shouldn’t be any )