We have been having great issues with z-fighting for quite a long time. Even when pushing the near-clip distance out as far as possible. A common technique these days for solving this is reversing the depth range as mentioned here:
https://developer.nvidia.com/content/de ... visualized
I decided to try it out in Ogre, with excellent results. With reversed-z we have pretty much no z-fighting issues at all anymore.
This page: https://nlguillemot.wordpress.com/2016/ ... in-opengl/ details the necessary changes.
Since I use the GL3Plus rendering system, I had to bump gl3w to a version containing glClipControl in order to set the clip range to 0-1. Beside that, the following changes were needed in order to test reversed-z in Ogre on the GL3Plus render system. The changes should be similar for D3D, aside from not needing to change the default clip parameters.
Code: Select all
diff --git a/Components/Hlms/Pbs/src/OgreHlmsPbs.cpp b/Components/Hlms/Pbs/src/OgreHlmsPbs.cpp
index 85addbd..1a3ed58 100644
--- a/Components/Hlms/Pbs/src/OgreHlmsPbs.cpp
+++ b/Components/Hlms/Pbs/src/OgreHlmsPbs.cpp
@@ -297,9 +297,9 @@ namespace Ogre
samplerblock.mMinFilter = FO_LINEAR;
samplerblock.mMagFilter = FO_LINEAR;
samplerblock.mMipFilter = FO_NONE;
- samplerblock.mCompareFunction = CMPF_LESS_EQUAL;
+ samplerblock.mCompareFunction = CMPF_GREATER;
if( !mShadowmapCmpSamplerblock )
mShadowmapCmpSamplerblock = mHlmsManager->getSamplerblock( samplerblock );
diff --git a/OgreMain/src/OgreHlmsDatablock.cpp b/OgreMain/src/OgreHlmsDatablock.cpp
index 42cf77a..337f6a7 100644
--- a/OgreMain/src/OgreHlmsDatablock.cpp
+++ b/OgreMain/src/OgreHlmsDatablock.cpp
@@ -54,9 +54,9 @@ namespace Ogre
BasicBlock( BLOCK_MACRO ),
mScissorTestEnabled( false ),
mDepthCheck( true ),
mDepthWrite( true ),
- mDepthFunc( CMPF_LESS_EQUAL ),
+ mDepthFunc( CMPF_GREATER ),
mDepthBiasConstant( 0 ),
mDepthBiasSlopeScale( 0 ),
mCullMode( CULL_CLOCKWISE ),
mPolygonMode( PM_SOLID )
diff --git a/OgreMain/src/OgreRectangle2D.cpp b/OgreMain/src/OgreRectangle2D.cpp
index 4100292..4abf1c4 100644
--- a/OgreMain/src/OgreRectangle2D.cpp
+++ b/OgreMain/src/OgreRectangle2D.cpp
@@ -124,25 +124,25 @@ namespace v1
{
//1st Top-left
*pVerts++ = -1.0f;
*pVerts++ = 1.0f;
- *pVerts++ = -1.0f;
+ *pVerts++ = 0.0f;
*pVerts++ = 0.0f;
*pVerts++ = 0.0f;
//2nd Bottom-left
*pVerts++ = -1.0f;
*pVerts++ = -3.0f; //3 = lerp( -1, 1, 2 );
- *pVerts++ = -1.0f;
+ *pVerts++ = 0.0f;
*pVerts++ = 0.0f;
*pVerts++ = 2.0f;
//3rd Top-right
*pVerts++ = 3.0f;
*pVerts++ = 1.0f;
- *pVerts++ = -1.0f;
+ *pVerts++ = 0.0f;
*pVerts++ = 2.0f;
*pVerts++ = 0.0f;
}
diff --git a/RenderSystems/GL3Plus/src/OgreGL3PlusDepthBuffer.cpp b/RenderSystems/GL3Plus/src/OgreGL3PlusDepthBuffer.cpp
index 1ad715d..b08d6c6 100644
--- a/RenderSystems/GL3Plus/src/OgreGL3PlusDepthBuffer.cpp
+++ b/RenderSystems/GL3Plus/src/OgreGL3PlusDepthBuffer.cpp
@@ -111,9 +111,9 @@ namespace Ogre
OCGE( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) );
OCGE( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST) );
OCGE( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) );
OCGE( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE) );
- OCGE( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL) );
+ OCGE( glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_GREATER) );
if( hasGL42 || support->checkExtension("GL_ARB_texture_storage") )
{
OCGE( glTexStorage2D( GL_TEXTURE_2D, GLint(1), depthFormat,
diff --git a/RenderSystems/GL3Plus/src/OgreGL3PlusRenderSystem.cpp b/RenderSystems/GL3Plus/src/OgreGL3PlusRenderSystem.cpp
index 9db3234..1c26100 100644
--- a/RenderSystems/GL3Plus/src/OgreGL3PlusRenderSystem.cpp
+++ b/RenderSystems/GL3Plus/src/OgreGL3PlusRenderSystem.cpp
@@ -635,9 +635,9 @@ namespace Ogre {
&depthFormat,
&stencilFormat );
DepthBuffer::DefaultDepthBufferFormat = PF_D32_FLOAT_X24_S8_UINT;
}
-
+ glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
mGLInitialised = true;
}
void GL3PlusRenderSystem::reinitialise(void)
@@ -2229,10 +2229,14 @@ namespace Ogre {
void GL3PlusRenderSystem::_convertProjectionMatrix(const Matrix4& matrix,
Matrix4& dest,
bool forGpuProgram)
{
+ Matrix4 reverse(1,0,0,0,
+ 0,1,0,0,
+ 0,0,-1,1,
+ 0,0,0,1);
// no any conversion request for OpenGL
- dest = matrix;
+ dest = reverse * matrix;
}
void GL3PlusRenderSystem::_makeProjectionMatrix(const Radian& fovy, Real aspect,
Real nearPlane, Real farPlane,
What remains to be done is to fix shadows, since the changes above also affect the shadowing passes, while the shaders are not adjusted for it.
I haven't done that yet. I am not sure how it will play with the pseudo-linear depth stuff Ogre uses, or if reversed-z is good or bad when it comes to shadows. In any case, either the shaders need adjustments, or Ogre has to be set up to use different depth comparisons when drawing the shadows.
I think this would be a very useful feature in mainline Ogre, when all issues have been worked out.