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

问题描述

上下文:

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

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

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

所以我的问题是:是否可以使用相同的深度纹理进行早期深度测试以及在着色器内部进行采样?否则,是否有其他方法(合理执行)拒绝其中没有几何图形的像素?在我的光照过程中,我根本不会写这种深度纹理。

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

解决方法

OpenGL中有一些规则,有关从着色器中读取数据的信息,由于帧缓冲操作,着色器中的数据也会进行更新。这些规则过去非常严格。实际上,在GL 4.4之前的版本中,rules were so strict实际上是未定义的行为。也就是说,如果将纹理中的图像附加到渲染FBO上,并且您以某种方式从该纹理中获取了一个样本,以使可能都可以从附加的图像中进行读取,则您有未定义的行为。没关系,如果您的书写蒙版意味着没有书写;是UB。

幸运的是,它现在定义明确。只有在进行实际写操作时,您才得到UB,这不仅是因为您已将图像附加到FBO。所谓“现在”,基本上是指过去10年中制造的所有硬件。尽管ARB_texture_barrier and GL 4.5是最近的版本,但它们的前身NV_texture_barrier实际上已经很旧了。尽管是NVIDIA扩展名,但so widely implemented还是even available on MacOS implementations