在GTX 980上进行深度预先通过后Z战斗

时间:2017-10-24 15:48:10

标签: opengl rendering depth-testing

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

GL_LEQUAL

似乎glDepthFunc未更改为glDepthFunc。但是,当我逐步完成RenderDoc中的GL调用时,words = [ 'look', 'into', 'my', 'eyes', 'look', 'into', 'my', 'eyes', 'the', 'eyes', 'the', 'eyes', 'the', 'eyes', 'not', 'around', 'the', 'eyes',"don't", 'look', 'around', 'the', 'eyes', 'look', 'into', 'my', 'eyes', "you're", 'under'] def requirement(word): onelist = [] if word in words: return(len(onelist.append(word))) print(map(requirement('look'), words)) 被设置为正确。

这听起来像是一个驱动程序错误,或者你有什么建议我可能做错了吗?当这是一个驱动程序错误时,我怎么能实现深度预先通过?

z-fighting on Nvidia GeForce GTX 980

2 个答案:

答案 0 :(得分:8)

当使用不同的着色器程序进行深度预处理时,必须明确确保该程序生成与主要通道的程序相同的深度值(尽管在相同的几何体上调用)。这是通过使用invariant上的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

gl_Position = ProjectionMatrix*ViewMatrix*ModelMatrix*vPosition;

将此更改为:

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

我解决了这个问题。

答案 1 :(得分:0)

Sponza的一些版本非常庞大。我记得我用两种解决方案中的一种解决了这个问题:

第二种方法在使用early depth test hidden surface removal的平铺体系结构方面较差。在移动平台上,性能下降可能非常明显。