Hen*_*nkk 3 opengl rendering depth-testing
我正在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(...);
Run Code Online (Sandbox Code Playgroud)
似乎glDepthFunc没有更改为GL_LEQUAL.但是,当我逐步完成RenderDoc中的GL调用时,glDepthFunc会设置为correnctly.
这听起来像是一个驱动程序错误,或者你有什么建议我可能做错了吗?当这是一个驱动程序错误时,我怎么能实现深度预先通过呢?
当使用不同的着色器程序进行深度预处理时,必须明确确保该程序生成与主通道程序相同的深度值(尽管在相同的几何图形上调用).这是通过使用invariant限定符来完成的gl_Position.
GLSL规范4.4解释的差异:
在本节中,方差指的是在不同程序中从同一表达式获取不同值的可能性.例如,假设两个顶点着色器在不同的程序中,每个着色器在两个着色器中都设置了相同的表达式,并且当两个着色器都运行时,该表达式中的输入值是相同的.由于两个着色器的独立编译,当两个着色器运行时,分配给gl_Position的值可能不完全相同.在此示例中,这可能导致多遍算法中几何对齐的问题.
在这种情况下,限定符的用法如下:
invariant gl_Position;
Run Code Online (Sandbox Code Playgroud)
此行保证gl_Position由着色器中给出的精确表达式计算而不进行任何优化,因为这会改变操作,因此很可能以某种小的方式更改结果.
在我的具体案例中,一项任务是问题的根源.主要通道的程序的顶点着色器包含以下行:
fWorldPosition = ModelMatrix*vPosition; // World position to the fragment shader
gl_Position = ProjectionMatrix*ViewMatrix*fWorldPosition;
Run Code Online (Sandbox Code Playgroud)
gl_Position在一个表达式中计算的预通道程序的顶点着色器:
gl_Position = ProjectionMatrix*ViewMatrix*ModelMatrix*vPosition;
Run Code Online (Sandbox Code Playgroud)
通过将其更改为:
vec4 worldPosition = ModelMatrix*vPosition;
gl_Position = ProjectionMatrix*ViewMatrix*worldPosition;
Run Code Online (Sandbox Code Playgroud)
我解决了这个问题.