Sign in to follow this  
seryogah

Logarithmic depth buffer issues with near objects

Recommended Posts

Hello,

 

I started writing on a virtual reality extension for an existing Google Earth-like project (which I haven't written myself).

Drawing the scene (mostly terrain and buildings in the far distance) works, but drawing the controllers with the same shader doesn't and I

see ugly artifacts/z fighting.

[sharedmedia=gallery:images:8028]
 
The problems seems to be the logarithmic z buffer that is beeing used because if I move the controllers further away from my face these artifacts seem to disappear,

The important code parts are

 

Vertex Shader:

#version 420
[..]
uniform float farPlane;
smooth out float flogz;

void main()
{
[..]
    gl_Position = viewProjModel * position;

    float C = 10.0;
    float Fcoef = 2.0 / log2(farPlane * C + 1.0);
    gl_Position.z = log2(max(1e-6, gl_Position.w * C + 1.0)) * Fcoef - 1.0;
    flogz = 1.0 + gl_Position.w * C;
}

Fragment Shader:

#version 420

#extension GL_ARB_conservative_depth : enable

layout(depth_less) out float gl_FragDepth;

uniform float farPlane;
smooth in float flogz;

[..]

void main()
{
[..]
    float C = 10.0;
    float Fcoef = 2.0 / log2(farPlane * C + 1.0);
    gl_FragDepth = log2(flogz) * Fcoef * 0.5;
}

The Framebuffer is created with

glGenFramebuffers(1, &renderFramebufferId);
glBindFramebuffer(GL_FRAMEBUFFER, renderFramebufferId);
		   
glGenRenderbuffers(1, &depthBufferId);
glBindRenderbuffer(GL_RENDERBUFFER, depthBufferId);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH_COMPONENT32, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBufferId);
		   
glGenTextures(1, &renderTextureId);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, renderTextureId);
glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, width, height, true);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, renderTextureId, 0);

GLenum statusRenderFB = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (statusRenderFB != GL_FRAMEBUFFER_COMPLETE)
{
    [..] // abort
}

I also played with different C-constants, different depth texture formats and with glEnable(GL_DEPTH_CLAMP) and nothing seems to help.

Does anyone know a solution? These artifacts bother me for days.

Share this post


Link to post
Share on other sites

Okay, I think I fixed it. It had nothing todo with the logarithmic depth buffer and was more of a problem with the 32 bit floating point precision (the position of my controller was around ~100000 in x,y,z).

Using a double matrix on a certain place fixed it (even though it seems more like a workaround).

Share this post


Link to post
Share on other sites

Seeing you're using OpenGL4, you could just use an inverted-z depth buffer instead of a logarithmic one, which has zero performance impact and doesn't cause interpolation artifacts.

https://nlguillemot.wordpress.com/2016/12/07/reversed-z-in-opengl/

(This was possible in D3D9 and has been the standard way to do Z-buffering for ever since, but GL needed to add glClipControl in GL4 before it was possible there)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this