是否可以在同一个绘制调用中针对我也在采样的深度纹理进行深度测试?

Is it possible to depth test against a depth texture I am also sampling, in the same draw call?

上下文:

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

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

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

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

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

OpenGL 中有关于从着色器中读取数据的规则,这些数据也会因帧缓冲区操作而更新。这些规则过去非常严格。事实上,pre-GL 4.4,rules were so strict 你试图做的实际上是未定义的行为。也就是说,如果来自纹理的图像附加到渲染 FBO,并且您从该纹理中获取样本的方式完全 可能 从附加的读取图像,你有未定义的行为。不要介意你的写掩码是否意味着没有写发生;是UB。

幸运的是,现在是 well-defined。如果您正在进行实际写入,您只会获得 UB,而不仅仅是因为您将图像附加到 FBO。我所说的“现在”基本上是指过去 10 年制造的所有硬件。而 ARB_texture_barrier and GL 4.5 are fairly recent, their predecessor NV_texture_barrier is actually quite old. And despite being an NVIDIA extension by name, it was so widely implemented that it is even available on MacOS implementations.