具有部分颜色写入的OpenGL全深度

时间:2014-11-24 07:23:44

标签: c++ opengl graphics 3d

我正在创建一个程序,它在两个单独的过程中渲染地形,中间有一个深度清除(无法更改此要求)。在第一遍中,我使用深度测试来渲染天空盒和地形。我将深度缓冲区位清除为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 Pass 1 Color Pass 1 Depth 通过2 Pass 2 Color Pass 2 Depth

如您所见,在第二次传递的单个绘图命令中,像素值正在深度缓冲区中写入,但颜色缓冲区仅部分写入。白色区域会引起一些奇怪的问题。

根据GDebugger的说法,这是我在绘制命令期间的状态:

  • GL_BLEND:TRUE
  • GL_BLEND_EQUATION_ALPHA:GL_FUNC_ADD
  • GL_BLEND_EQUATION:GL_FUNC_ADD
  • GL_BLEND_EQUATION_RGB:GL_FUNC_ADD
  • GL_BLEND_DST:0
  • GL_BLEND_DST_ALPHA:0
  • GL_BLEND_DST_RGB:0
  • GL_BLEND_SRC:1
  • GL_BLEND_SRC_ALPHA:1
  • GL_BLEND_SRC_RGB:1
  • GL_DEPTH_FUNC:GL_LESS
  • GL_DEPTH_TEST:TRUE
  • GL_STENCIL_FUNC:GL_ALWAYS
  • GL_STENCIL_TEST:FALSE
  • GL_BLEND_COLOR:{0,0,0,0}

谁能告诉我发生了什么事?我觉得GPU让我眼前一亮。

编辑:

  • 我目前有一个活着的GL上下文。
  • 我的显卡是英特尔HD 4000,最新的驱动程序在带有8 GB RAM的Intel i7上运行。
  • MY FBO的颜色附件的内部格式为GL_RGBA16F,深度附件为GL_DEPTH_COMPONENT32F。
  • 从不使用模板测试。

1 个答案:

答案 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。去图。