首页 > 解决方案 > 是否可以在同一个绘图调用中针对我也在采样的深度纹理进行深度测试?

问题描述

语境:

我正在使用延迟渲染设置,在第一阶段我有两个 FBO:一个是 GBuffer,用于存储所有可见片段的法线、反照率和材质信息。此 FBO 具有 32 位深度纹理。在计算任何光照之前,这会被绘制到几何通道中。

第二个 FBO 是纯颜色的,从黑色开始,但在多个通道中累积光照,来自从 GBuffer 采样并使用加法混合写入纯颜色缓冲区的光照着色器。

问题是,我真的很想利用早期深度测试来让我的光照只计算包含实际几何图形的片段(不仅仅是天空)。我能想到的最好方法是使用深度测试来使在阳光下深度为 1 的任何像素失效,或者使位于点光源影响范围后面的任何像素失效。但是,我不认为我可以将此深度纹理​​绑定到我的颜色 FBO,因为我还在光照着色器中对其进行采样以计算片段在世界空间中的位置。

所以我的问题是:有没有办法为早期深度测试和着色器内部的采样使用相同的深度纹理?或者,如果没有,是否有其他(合理的性能)方法来拒绝其中没有几何图形的像素?在我的光照通道中,我根本不会写入这个深度纹理。

我只需要针对 PC 上的现代图形硬件(所以我可以使用任何常见的扩展或 openGL 4.6 功能)。

标签: openglfboopengl-4deferred-rendering

解决方案


OpenGL 中有一些关于从着色器中读取数据的规则,这些数据也由于帧缓冲操作而被更新。这些规则过去非常严格。事实上,在 GL 4.4 之前,规则非常严格,以至于您尝试做的实际上是未定义的行为。也就是说,如果纹理中的图像附加到渲染 FBO,并且您以一种完全有可能从附加图像中读取的方式从该纹理中获取样本,那么您会得到未定义的行为。没关系,如果您的写掩码意味着没有发生任何写操作;是UB。

幸运的是,它现在定义明确。只有在进行实际写入时才能获得 UB,而不仅仅是因为您将图像附加到 FBO。我所说的“现在”基本上是指过去 10 年制造的任何硬件。虽然ARB_texture_barrier 和 GL 4.5是相当新的,但它们的前身 NV_texture_barrier 实际上已经很老了。尽管名称上是 NVIDIA 扩展,但它的实现如此广泛甚至可以在 MacOS 实现上使用


推荐阅读