Shadow Map Reduce Problem

In order to compute tight bounds for my shadow maps, I render a depth only pass, and then I read back the depth to compute the min and the max. I currently render to a FBO with a 32 bit depth attachment.

I also have an unusual situation in that my near clip is 0.01, my far is 100000, and my FOV is less than 1 degree. With this setup, I noticed that the shadows flicker on and off. When the shadows are missing, both the raw min and the max depth buffer values are 4294959103. The scene I’m looking should range from ~5000m to 5300m away (which is what is computed when the shadows are “on”). Granted, I have an extreme frustum, but a 32 bit depth buffer should be able to handle it.

Could anyone point me in the right direction? Any help would be greatly appreciated.

[QUOTE=TheHighlander;1279038]In order to compute tight bounds for my shadow maps, I render a depth only pass, and then I read back the depth to compute the min and the max. I currently render to a FBO with a 32 bit depth attachment.

I also have an unusual situation in that my near clip is 0.01, my far is 100000, and my FOV is less than 1 degree. With this setup, I noticed that the shadows flicker on and off. When the shadows are missing, both the raw min and the max depth buffer values are 4294959103. The scene I’m looking should range from ~5000m to 5300m away (which is what is computed when the shadows are “on”). Granted, I have an extreme frustum, but a 32 bit depth buffer should be able to handle it.[/QUOTE]

Bear in mind that the computations will probably use single-precision floating-point internally, meaning that you only have 24 bits of precision. At Z=-5000, adjacent depth values will be roughly 75 units apart.

A depth value of 4294959103 corresponds to a Z value of around -4981.

If you’re looking at something 5 km away, do you really need a near distance of 10 mm?

Thanks for your response. If that’s the case, what’s the point of a 32 bit depth buffer?

Unfortunately I’m not always looking at things 5km away. Sometimes I am though and I also have part of aircraft in the scene close to the near clip.

Also, if depth buffer precision were a problem, I’d think I’d see other artifacts like z fighting in my scene.

Hmm… Let’s see. For just computing a quick scene min/max depth to bound the region which may receive shadows, you don’t really need to worry about the stuff super close to the eyepoint, if you have a shadow split that handles receiving shadows for the stuff really close to the eye, or you decide you’re not going to let that stuff receive shadows.

With this, for the purposes of computing the near/far, just push the near clip out to 1 … 5 or so to get a better bounds on the stuff further away from the eyepoint than 1…5 units, and then blast the stuff nearer than 1…5 units into a shadow map for objects close to the eye.

Alternatively I guess you could use depth partitioning to compute your true scene bounds (i.e. do a NEAR subfrustum depth pass and min/max compute, and then do a FAR subfrustum depth pass and min/max compute; then unify these to get a single min/max range). That’s possible.

And for fun, there’s also alternative depth buffer schemes (log, linear, pseudo-linear, etc.) which can defeat pipeline optimizations but can improve depth accuracy.

You could also try a GL_DEPTH_COMPONENT_32F depth rendertarget instead of a GL_DEPTH_COMPONENT32, possibly with an inverted depth buffer. But not sure if that’ll give you the extra accuracy you’re looking for.

Might be simplest just to chuck the near stuff into a “close to eyepoint” split and min/max crunch the rest in a single pass.

If you don’t have a stencil buffer, 4-byte alignment may be more efficient than 3-byte alignment.

If there’s a distinct set of geometry that’s much closer to the viewpoint than the rest of the scene, I’d suggest rendering it last with its own projection matrix (you can either clear the depth buffer between rendering phases or use glDepthRange() to allocate a portion of the range to the near geometry).