gpt4 book ai didi

opengl - GTX 980 深度预通过后的 Z-fighting

转载 作者:行者123 更新时间:2023-12-01 08:49:18 28 4
gpt4 key购买 nike

我正在 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 设置正确。

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

z-fighting on Nvidia GeForce GTX 980

最佳答案

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

GLSL 规范 4.4 解释的差异:

In this section, variance refers to the possibility of getting different values from the same expression in different programs. For example, say two vertex shaders, in different programs, each set gl_Position with the same expression in both shaders, and the input values into that expression are the same when both shaders run. It is possible, due to independent compilation of the two shaders, that the values assigned to gl_Position are not exactly the same when the two shaders run. In this example, this can cause problems with alignment of geometry in a multi-pass algorithm.



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

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

在我的具体案例中,作业是问题的根源。主 channel 程序的顶点着色器包含以下几行:
fWorldPosition = ModelMatrix*vPosition; // World position to the fragment shader
gl_Position = ProjectionMatrix*ViewMatrix*fWorldPosition;

prepass 程序的顶点着色器在一个表达式中计算 gl_Position:
gl_Position = ProjectionMatrix*ViewMatrix*ModelMatrix*vPosition;

通过将其更改为:
vec4 worldPosition = ModelMatrix*vPosition;
gl_Position = ProjectionMatrix*ViewMatrix*worldPosition;

我解决了这个问题。

关于opengl - GTX 980 深度预通过后的 Z-fighting,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46914862/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com