如何实现两次通过之间的深度值不变性?

And*_*urg 5 opengl glsl

我有两个几何通道.在第一遍中,我将片段的深度值写入浮点纹理glBlendEquation(GL_MIN),类似于双深度剥离.在第二遍中,我使用它在片段着色器中进行早期深度测试.

但是,对于某些片段,深度测试会失败,除非我略微偏移最小深度值(eps下面):

在此输入图像描述

设置纹理:

glBindTexture(GL_TEXTURE_2D, offscreenDepthMapTextureId);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, screenWidth, screenHeight);

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, offscreenDepthMapFboId);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
  offscreenDepthMapTextureId, 0);
Run Code Online (Sandbox Code Playgroud)

请注意,纹理用作颜色附件,而不是深度附件.我GL_DEPTH_TEST在两次传球都禁用了,因为我不能在最后一次传球中使用它.

顶点着色器,用于两个过程:

#version 430

layout(location = 0) in vec4 position;

uniform mat4 mvp;
invariant gl_Position;

void main()
{
  gl_Position = mvp * position;
}
Run Code Online (Sandbox Code Playgroud)

第一次传递片段着色器,带有offscreenDepthMapFboId边界,因此它将深度作为颜色写入纹理.混合确保只有最小值最终在红色组件中.

#version 430

out vec4 outputColor;

void main()
{
  outputColor.rg = vec2(gl_FragCoord.z, -gl_FragCoord.z);
}
Run Code Online (Sandbox Code Playgroud)

第二遍,写入默认的帧缓冲区.纹理用作depthTex.

#version 430

out vec4 outputColor;

uniform sampler2D depthTex;

void main()
{
  vec2 zwMinMax = texelFetch(depthTex, ivec2(gl_FragCoord.xy), 0).rg;
  float zwMin = zwMinMax.r;
  float zwMax = -zwMinMax.g;
  float eps = 0;// doesn't work
  //float eps = 0.0000001; // works
  if (gl_FragCoord.z > zwMin + eps)
    discard;
  outputColor = vec4(1, 0, 0, 1);
}
Run Code Online (Sandbox Code Playgroud)

顶点着色器中的不变限定符没有帮助.使用eps = 0.0000001似乎是一个粗略的解决方法,因为我不能确定这个特定值将始终有效.如何让两个着色器生成完全相同的gl_FragCoord.z?或深度纹理是问题?错误的格式?是否有任何我不知道的转换?

Mar*_*ius 1

您是否尝试过 glDepthFunc(GL_EQUAL) 而不是着色器内比较方法?您是否在同一通道中读取和写入相同的深度纹理?

我不确定 gl_FragCoord 的格式和精度是否与深度缓冲区之一相关。这也可能是驱动程序故障,但 glDepthFunc(GL_EQUAL) 应该按预期工作。