我正在创建一个程序,它在两个单独的过程中渲染地形,中间有一个深度清除(无法更改此要求)。在第一遍中,我使用深度测试来渲染天空盒和地形。我将深度缓冲区位清除为1.0。然后,我也用深度测试渲染我所有的近地。所以代码看起来像这样:
// My State
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ZERO);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glDepthFunc(GL_LESS);
glClearColor(0, 0, 0, 0);
glClearDepth(1.0);
// Pass 1
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
DrawSkybox();
DrawFarTerrain();
// Pass 2
glClear(GL_DEPTH_BUFFER_BIT);
DrawNearTerrain(); // IMPORTANT: All done in one draw command
以下图像显示每次传递结束时的颜色值和深度(白色= 1.0):
通过1 通过2
如您所见,在第二次传递的单个绘图命令中,像素值正在深度缓冲区中写入,但颜色缓冲区仅部分写入。白色区域会引起一些奇怪的问题。
根据GDebugger的说法,这是我在绘制命令期间的状态:
谁能告诉我发生了什么事?我觉得GPU让我眼前一亮。
编辑:
答案 0 :(得分:2)
好吧,我和遇到过这样的错误的人交谈过,我在这个过程中解决了这个问题。
事实证明,第一遍结束时白色部分的所有部分都不是白色,而实际上是NaN。 GDEBugger将值显示为(255,255,255,255),因为它不能支持显示任何其他纹理格式。它只是说:" NaN,你必须是白色的:P"。
那么,为什么NaN在我们进行像素替换时很重要 - glBlendFunc(GL_ONE,GL_ZERO)。这是因为NaN上的操作仍然会导致NaN一直向下通过管道。 GL实现仍然执行" Result = SourceFactor * Source + DestFactor * Dest" - 未执行任何优化。
关于修复...结果表明执行" outFragColor = clamp(outFragColor,vec4(0.0),vec4(3000000000000.0))"在片段阶段(outFragColor是像素返回值)将不会导致NaN,即使outFragColor包含NaN。去图。