• Advertisement
Sign in to follow this  

Logarithmic depth buffer issues with near objects

This topic is 495 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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
Advertisement

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
Sign in to follow this  

  • Advertisement