Outerra's Depth Buffer AnalysisMany of our customers struggle with depth buffer resolution issues, due to the massive scenes they must represent in training and simulation systems. 2015 seems to have been the year of the logarithmic depth buffer, but going into 2016 we’re seeing more customers also experimenting with reverse depth buffers (AKA inverse depth buffers).

Reverse depth buffers operate on the observation that floating-point depth buffer formats tend to concentrate resolution near the depth value of 0. This is especially weird in OpenGL, which maps its depth range from -1 to 1, putting that area of concentrated resolution in the middle of the scene where it doesn’t do much good. Detailed write-ups are available from Outerra and NVidia that explain how this trick works. But the bottom line is, OpenGL users can sometimes just call glDepthRangedNV(-1,1) and be done with it. (Yes, that works on AMD/ATI cards too.)

However, SilverLining and Triton both make some assumptions based on the depth range, so you need to tell them if you’re messing with the depth range values.

If your application is using a reverse depth buffer, you can tell Triton about it by modifying these settings in the Resources/Triton.config file:

# Adjusts our assumptions about the range of projected Z values in your application's
# projection matrix. If you are using an unusual projection matrix, such as for a
# reverse floating point depth buffer in OpenGL, you can adjust the near and far
# z values here.
opengl-near-clip = -1.0
opengl-far-clip = 1.0
directx-near-clip = 0.0
directx-far-clip = 1.0

Be sure you’re using Triton version 3.48 or newer for this to work properly.

In SilverLining, use the Atmosphere::SetDepthRange() method:

/** Call this at the beginning of each rendering loop, prior to calling DrawSky(), indicating
the range of depth buffer values in use. Calling this is optional, but may result in
avoiding a stall each frame. Normally, the near depth value is 0.0 and the far depth
value is 1.0, unless you're doing something like implementing reversed floating point
depth buffers.
\param nearDepth The z value that is mapped to the near clipping plane. (Usually 0)
\param farDepth The z value that is mapped to the far clipping plane. (Usually 1)
void SILVERLINING_API SetDepthRange(float nearDepth, float farDepth);

Between this and our extensible shader framework, you’ve got all the tools you need to integrate SilverLining and Triton into pretty much any exotic depth buffer scheme you can dream up. Go get rid of your z-fighting!

*Image credit: Outerra