同时用作着色器程序的 FBO 颜色附件和 sampler2D 的纹理

Texture used as FBO color attachment and sampler2D of a shader program at the same time

我创建了一个 FBO 并将纹理绑定作为其颜色附件,并且我有多个着色器程序对纹理进行一些 post 处理,一切都很好,但没有意义我认为纹理可以同时用作输入(sampler2D)和着色器的输出

以下是我采取的步骤:

  1. 创建 FBO fboA
  2. 创建纹理 textureA,并将其绑定为 fboA 的颜色附件。
  3. 调用 glBindFrameBufferfboA 绑定到帧缓冲区目标。
  4. 调用glUseProgram使用着色器程序shaderA
  5. 调用glDrawArrays画东西(最终在textureA上画,因为fboA当前绑定)。
  6. 调用glUseProgram使用着色器程序shaderB,它在片段着色器中有sampler2D统一。
  7. textureA 绑定为 sampler2D 着色器程序的制服 shaderB
  8. 在片段着色器中,textureA用于设置fragColor

让我感到困惑的是最后两步,其中textureA用作片段着色器的输入,仍然绑定到当前帧缓冲区。在我看来,片段着色器正在读取和写入同一块内存,这不是某种未定义的行为,为什么它仍然可以正常工作?

isn't this some kind of undefined behaviors, why it still works correctly?

因为“undefined behavior”并不排除该行为可能看起来“正常工作”的可能性。 UB 意味着任何事情 都可能发生,包括您真正希望发生的事情。

当然,明天它可能突然停止“工作”。或者当您将代码带到不同的 GPU 时。或者如果你开始渲染更多的东西。或者,如果您在计算机上呼吸非常困难。

未定义的行为是未定义

如果你想让它定义明确,那么你需要使用 texture barrier 功能并遵守它的规则:障碍之间的每个片段不超过一个 read/modify/write,或者只是阅读从和写入非重叠片段集。