同时用作着色器程序的 FBO 颜色附件和 sampler2D 的纹理
Texture used as FBO color attachment and sampler2D of a shader program at the same time
我创建了一个 FBO 并将纹理绑定作为其颜色附件,并且我有多个着色器程序对纹理进行一些 post 处理,一切都很好,但没有意义我认为纹理可以同时用作输入(sampler2D)和着色器的输出。
以下是我采取的步骤:
- 创建 FBO
fboA
。
- 创建纹理
textureA
,并将其绑定为 fboA
的颜色附件。
- 调用
glBindFrameBuffer
将 fboA
绑定到帧缓冲区目标。
- 调用
glUseProgram
使用着色器程序shaderA
。
- 调用
glDrawArrays
画东西(最终在textureA
上画,因为fboA
当前绑定)。
- 调用
glUseProgram
使用着色器程序shaderB
,它在片段着色器中有sampler2D
统一。
- 将
textureA
绑定为 sampler2D
着色器程序的制服 shaderB
。
- 在片段着色器中,
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,或者只是阅读从和写入非重叠片段集。
我创建了一个 FBO 并将纹理绑定作为其颜色附件,并且我有多个着色器程序对纹理进行一些 post 处理,一切都很好,但没有意义我认为纹理可以同时用作输入(sampler2D)和着色器的输出。
以下是我采取的步骤:
- 创建 FBO
fboA
。 - 创建纹理
textureA
,并将其绑定为fboA
的颜色附件。 - 调用
glBindFrameBuffer
将fboA
绑定到帧缓冲区目标。 - 调用
glUseProgram
使用着色器程序shaderA
。 - 调用
glDrawArrays
画东西(最终在textureA
上画,因为fboA
当前绑定)。 - 调用
glUseProgram
使用着色器程序shaderB
,它在片段着色器中有sampler2D
统一。 - 将
textureA
绑定为sampler2D
着色器程序的制服shaderB
。 - 在片段着色器中,
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,或者只是阅读从和写入非重叠片段集。