Reverse-Z rendering

classic Classic list List threaded Threaded
1 message Options
Himbeertoni Himbeertoni
Reply | Threaded
Open this post in threaded view
|

Reverse-Z rendering

Hi,
The reverse-z rendering technique (see https://nlguillemot.wordpress.com/2016/12/07/reversed-z-in-opengl/ and https://developer.nvidia.com/content/depth-precision-visualized) allows for increased depth precision with large scenes and view distances, a scenario which is a good fit for osgEarth as well I think.

With the stock OSG viewer there is no such support I think, but I'm writing a custom viewing application and renderer and use osgEarth as library. Besides the measures taken in the aforementioned articles (Rendering to an FBO with 32-bit float depth buffer, glClipControl, and a reversed projection matrix) I got this technique to work with osgEarth by modifying the osgEarth source in the following way:
In the function:
void RexTerrainEngineNode::updateState()
I set the depth comparison function to Greater Or Equal instead of Less Or Equal:
        // required for multipass tile rendering to work
        surfaceStateSet->setAttributeAndModes(
            new osg::Depth(Registry::instance()->applicationUsesReverseZ() ? osg::Depth::GEQUAL : osg::Depth::LEQUAL, 0, 1, true));
Note that I added a variable to the osgEarth::Registry to be able to toggle Reverse-Z at runtime. This allows for the terrain tiles to be rendered, but the same check has to be done for the annotations in AnnotationUtils.cpp, AnnotationNode.cpp and for the ClampingBinTechnique as well I think (I don't use that feature).

Also note that the automatic update of the projection matrix based on scene boundaries should be disabled to prevent OSG from changing the projection matrix. This can require a custom ClampProjectionMatrixCallback or in case of using an infinite far plane setup, the near-far-computation can be disabled with the command:
view->getCamera()->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);

Maybe that information was useful to some. This technique is probably a better alternative than the provided LogarithmicDepthBuffer.