【问题标题】:Reading FBO depth attachment whilst depth testing在深度测试时读取 FBO 深度附件
【发布时间】:2015-07-23 00:12:12
【问题描述】:

我正在使用使用 OpenGL 3.3 的延迟渲染引擎。我有一个 FBO 设置为我的 G 缓冲区,并附有一个纹理作为深度组件。

在我的光照通道中,我需要进行深度测试(禁用写入)以剔除不必要的像素。但是,我目前正在编写重建世界位置坐标的代码,这也需要访问深度缓冲区。

在 Opengl 3.3 中将深度附件绑定到纹理单元并对其进行采样,同时在同一通道中使用它进行深度测试是否合法?

我在文档中找不到任何关于它的具体内容,但我的直觉告诉我,将相同的缓冲区/纹理用于两种不同的目的会产生未定义的行为。有人确定吗?我有一组有限的硬件可供测试,并且不想对有效的硬件做出错误的假设。

【问题讨论】:

  • this thread 中的评论表明这是未定义的行为。因为我找不到任何确定的东西,所以让问题悬而未决。
  • Fibbles 是对的。据我所知,您无法在同一通道中读写 FBO。而且由于采样正在读取 FBO 并渲染到深度缓冲区正在写入,这可能不起作用。
  • 检查规范后,我同意您链接的线程中的 Alfonse Reinheart。常识表明,如果您禁用深度写入,这可能没问题。但是我在规范中找不到任何特别允许这样做的东西。按照我的阅读方式,这仍然符合渲染反馈循环的条件,即使禁用了深度写入,因此行为是未定义的。
  • 我最终在各种硬件/驱动程序上进行了测试,结果肯定是不确定的。我最终不得不使用深度附件和 GL_R32F 颜色附件来实现 G-Buffer,其中还包含深度信息,以便稍后在照明通道中读取它。乍一看似乎很浪费,但它仍然比我之前使用的深度附件加上 GL_RGB32F 颜色附件(用于世界坐标)更有效。

标签: opengl opengl-3 fbo depth-buffer


【解决方案1】:

这至少会造成无法保证内存一致性的情况(一致性是您在 GL4 之前的传统管道的所有阶段都假设的东西,并且对任何一个都没有标准化控制)。

驱动程序可能会以不希望的方式缓存此内存,因为此行为未定义。您会认为写掩码和采样的适当组合会强烈暗示不要这样做,但这完全取决于设计驱动程序的人,您的结果往往会因硬件供应商、平台和硬件代而异。

这个场景是 NV 的纹理屏障扩展之类的用例,但这是特定于供应商的,仍然不能完全解决问题。如果你想便携地做这类事情,最好的办法是将引擎升级到 GL4,并使用标准化功能进行早期片段测试、障碍等。


您的复合通道是否真的首先需要深度缓冲区?听起来您想在从存储的深度缓冲区照明期间重新构建每个像素的位置。这在完全没有深度附件的帧缓冲区中是完全可能的。

此时您的 G-Buffers 已被填充,之后您不再需要进行任何片段测试。通过所有先前测试的片段是最终写入 G-Buffer 的片段,在进行光照时没有理由对其应用任何额外测试。

【讨论】:

  • 我已经接受了您的回答,但我们希望您能提供一些参考资料。
  • 在光照过程中需要进行片段测试。例如,点光源使用球形边界体积。体积内的所有片段都运行光照计算。如果没有深度测试,球形边界体积实际上是从相机延伸到远剪辑平面的圆柱体。如果点光源距离较远,则无关紧要,因为圆柱体直径很小。如果它很接近,我们会遇到最坏的情况;圆柱体是如此之宽,以至于覆盖了整个屏幕。通过执行 GEQUAL 深度测试,体积后面的片段永远不会收到光照计算。
  • 哦,我明白了。我完全使用了不同的方法,在照明之前我有一个预通行证,可以将所有东西分解成瓷砖。对于每个图块,我都有一个覆盖它的灯光列表(这是进行深度/模板测试的地方)。到合成灯光时,就不再需要对任何类型的每个片段进行测试了。通过为未完全覆盖的图块内的像素评估光照着色器会产生一些额外的工作量,但它最终会自行解决,因为可以从计算着色器而不是片段来评估这些图块。不过那是 GL4 时代的东西。
  • 在 GL3 中,我认为大多数地方都会让您开始使用模板缓冲区进行覆盖测试,而不是深度缓冲区。最明显的好处来自点光源——一个像素可以处于三种可能的状态之一(太近)、(内部)或(太远)。单个深度测试(给出二进制结果)无法正确处理该问题,您将处理误报。由于您不能(无论如何在 GL3 中)从着色器中对模板缓冲区进行采样,因此如果您在光照期间的覆盖测试使用它而不是深度缓冲区,您还可以避免我的回答中讨论的一致性问题。
  • 虽然如此准确,但我从未见过任何切实的性能优势。平铺所有内容也一样有效,并且具有您可以想象的最简单的覆盖标准。
猜你喜欢
  • 1970-01-01
  • 2013-11-22
  • 1970-01-01
  • 2022-10-22
  • 1970-01-01
  • 1970-01-01
  • 2018-10-28
  • 2016-08-15
  • 1970-01-01
相关资源
最近更新 更多