在深度测试时读取 FBO 深度附件

Reading FBO depth attachment whilst depth testing

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

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

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

我在文档中找不到任何关于它的具体信息,但我的直觉告诉我,将相同的 buffer/texture 用于两个不同的目的会产生未定义的行为。有人确定吗?我只有一组有限的硬件可以测试,不想对什么有效做出错误的假设。

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

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

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


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

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