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

Posted

技术标签:

【中文标题】纹理同时用作着色器程序的 FBO 颜色附件和 sampler2D【英文标题】:Texture used as FBO color attachment and sampler2D of a shader program at the same time 【发布时间】:2017-08-08 15:19:19 【问题描述】:

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

以下是我采取的步骤:

    创建一个 FBO fboA。 创建纹理textureA,并将其绑定为fboA的颜色附件。 调用glBindFrameBufferfboA 绑定到帧缓冲区目标。 调用glUseProgram使用着色器程序shaderA。 调用glDrawArrays 绘制一些东西(最终在textureA 上绘制,因为fboA 当前已绑定)。 调用glUseProgram 以使用在片段着色器中具有sampler2D 统一的着色器程序shaderB。 将textureA绑定为sampler2D着色器程序的统一shaderB。 在片段着色器中,textureA 用于设置fragColor

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

【问题讨论】:

【参考方案1】:

这不是某种未定义的行为,为什么它仍然可以正常工作?

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

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

未定义的行为是未定义的

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

【讨论】:

谢谢,正是我想知道的。我也只是指向Feedback Loops。

以上是关于纹理同时用作着色器程序的 FBO 颜色附件和 sampler2D的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL 片段着色器未写入 fbo 颜色缓冲区

GLSL MRT 将相同的数据写入所有颜色附件

使用 FBO 和着色器 OpenGL 渲染到纹理

是否可以将默认渲染缓冲区附加到 FBO?

GLSL:无法从 FBO 读取纹理并使用片段着色器渲染到另一个 FBO

OpenGL 帧缓冲区颜色附件到计算着色器