我有两个几何通道。在第一遍中,我将片段的深度值写入具有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);
请注意,纹理用作颜色附件,而不是深度附件。我在两次传球中都禁用了GL_DEPTH_TEST
,因为我无法在最后一次传球中使用它。
顶点着色器,用于两个传递:
#version 430
layout(location = 0) in vec4 position;
uniform mat4 mvp;
invariant gl_Position;
void main()
{
gl_Position = mvp * position;
}
第一次传递片段着色器,绑定offscreenDepthMapFboId
,因此它将深度作为颜色写入纹理。混合确保只有最小值在红色组件中结束。
#version 430
out vec4 outputColor;
void main()
{
outputColor.rg = vec2(gl_FragCoord.z, -gl_FragCoord.z);
}
第二遍,写入默认的帧缓冲区。纹理用作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);
}
顶点着色器中的不变限定符没有帮助。使用eps = 0.0000001
似乎是一个粗略的解决方法,因为我无法确定这个特定的值是否总是有效。如何让两个着色器生成完全相同的gl_FragCoord.z
?或深度纹理是问题?错误的格式?是否有任何我不知道的转换?
答案 0 :(得分:1)
您是否尝试过glDepthFunc(GL_EQUAL)而不是in-shader-comparison-approach? 你是否在同一个传递中读写相同的深度纹理?
我不确定gl_FragCoord的格式和精度是否与深度缓冲区之一相关。此外,它可能是一个驱动程序故障,但glDepthFunc(GL_EQUAL)应该按预期工作。
答案 1 :(得分:0)
不要使用gl_FragCoord.z作为深度值。
在顶点着色器中:
out float depth;
void main()
{
...
depth = ((gl_DepthRange.diff * (gl_Position.z / glPosition.w)) +
gl_DepthRange.near + gl_DepthRange.far) / 2.0;
}