在帧缓冲区和活动纹理之间形成WebGL反馈循环

WebGL feedback loop formed between Framebuffer and active Texture

我有一个webgl项目设置,该设置使用2遍渲染在纹理上创建效果。

一切正常,直到最近chrome开始引发此错误:

1
[.WebGL-0000020DB7FB7E40] GL_INVALID_OPERATION: Feedback loop formed between Framebuffer and active Texture.

即使我没有更改代码,这也只是开始发生,所以我猜测是由新的更新引起的。

我在SO上找到了这个答案,并指出错误"发生在您从当前连接到帧缓冲区的纹理读取的任何时候发生"。

但是我已经梳理了100次代码,但我不相信自己在这样做。所以这就是我的设置方法。

使用统一采样器创建片段着色器。

1
uniform sampler2D sampler;

创建2个纹理

1
2
var texture0 = initTexture(); // This function does all the work to create a texture
var texture1 = initTexture(); // This function does all the work to create a texture

创建一个帧缓冲区

1
var frameBuffer = gl.createFramebuffer();

然后,我通过将html图像上传到texture0,然后将texture0绑定到采样器来开始" 2遍处理"。

然后,我绑定帧缓冲区并调用drawArrays:

1
2
3
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture1, 0);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);

要清理,我取消绑定帧缓冲区:

1
gl.bindFramebuffer(gl.FRAMEBUFFER, null);

编辑:

在我的代码中添加断点之后,我发现直到我绑定空帧缓冲区后才真正抛出该错误。因此drawArrays调用不会引起错误,它随后绑定了将其设置为空的空帧缓冲区。


从83版开始,Chrome开始对帧缓冲区和活动的纹理反馈循环执行保守检查。 这些检查可能过于保守,并且会影响应实际允许的使用情况。

在这些新检查中,Chrome似乎不允许将渲染目标绑定到任何纹理插槽,即使程序未使用该插槽也是如此。

在您的两阶段渲染中,您可能会遇到以下情况:

  • 初始化渲染目标并创建指向帧缓冲区的纹理。
  • 渲染到目标。
  • 在1中,您可能需要使用gl.bindTexture(gl.TEXTURE_2D,yourTexture)绑定纹理,然后在步骤2之前,使用gl.bindTexture(gl.TEXTURE_2D,null)取消绑定纹理; 否则,即使渲染纹理没有被程序采样,Chrome也会因为渲染目标绑定为纹理而失败。