4

我正在 OpenGL 中实现深度预通。在 Intel HD Graphics 5500 上,此代码可以正常工作,但在 Nvidia GeForce GTX 980 上却不行(下图显示了由此产生的 z-fighting)。我正在使用以下代码生成图像。(与问题无关的所有内容都被省略了。)

// ----------------------------------------------------------------------------
// Depth Prepass
// ----------------------------------------------------------------------------

glEnable(GL_DEPTH_TEST);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glDepthFunc(GL_LESS);
glDepthMask(GL_TRUE);

glUseProgam(program1); // The problem turned out to be here!

renderModel(...);

// ----------------------------------------------------------------------------
// Scene Rendering
// ----------------------------------------------------------------------------

glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glDepthMask(GL_FALSE);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

glUseProgam(program2); // The problem turned out to be here!

renderModel(...);

似乎 glDepthFunc 没有更改为GL_LEQUAL. 但是,当我单步执行 RenderDoc 中的 GL 调用时,glDepthFunc设置正确。

这听起来像驱动程序错误还是您有建议我可能做错了什么?当这是一个驱动程序错误时,我该如何实现深度预通?

Nvidia GeForce GTX 980 上的 z-fighting

4

2 回答 2

11

当为深度预通道使用不同的着色器程序时,必须明确确保该程序生成与主通道程序相同的深度值(尽管在相同的几何体上调用)。这是通过使用invariant限定词 on完成的gl_Position

GLSL 规范 4.4 解释的差异:

在本节中,方差是指在不同程序中从同一个表达式得到不同值的可能性。例如,假设两个顶点着色器,在不同的程序中,每个设置 gl_Position 在两个着色器中具有相同的表达式,并且当两个着色器运行时该表达式的输入值是相同的。由于两个着色器的独立编译,有可能在两个着色器运行时分配给 gl_Position 的值并不完全相同。在此示例中,这可能会导致多通道算法中的几何对齐问题。

在这种情况下,限定符的使用如下:

invariant gl_Position;

这条线保证gl_Position由着色器中给出的精确表达式计算而无需任何优化,因为这会改变操作,因此很可能会以某种较小的方式改变结果。

在我的具体情况下,分配是问题的根源。主通道程序的顶点着色器包含以下几行:

fWorldPosition = ModelMatrix*vPosition; // World position to the fragment shader
gl_Position = ProjectionMatrix*ViewMatrix*fWorldPosition;

gl_Position在一个表达式中计算的 prepass 程序的顶点着色器:

gl_Position = ProjectionMatrix*ViewMatrix*ModelMatrix*vPosition;

通过将其更改为:

vec4 worldPosition = ModelMatrix*vPosition;
gl_Position = ProjectionMatrix*ViewMatrix*worldPosition;

我解决了这个问题。

于 2017-10-24T21:25:15.350 回答
0

Sponza 的某些版本很大。我记得我用两种解决方案之一解决了这个问题:

第二种方法在利用早期深度测试去除隐藏表面的平铺架构上效果较差。在移动平台上,性能下降可能非常明显。

于 2017-10-24T18:35:04.310 回答