在帧缓冲区和活动纹理之间形成的 WebGL 反馈循环
WebGL feedback loop formed between Framebuffer and active Texture
我有一个 webgl 项目设置,它使用 2 pass 渲染在纹理上创建效果。
一切正常,直到最近 chrome 开始抛出此错误:
[.WebGL-0000020DB7FB7E40] GL_INVALID_OPERATION: Feedback loop formed between Framebuffer and active Texture.
虽然我没有更改我的代码,但这种情况才刚刚开始发生,所以我猜是新的更新导致了这种情况。
我在 SO 上找到 ,指出错误 "happens any time you read from a texture which is currently attached to the framebuffer"。
然而,我已经梳理了我的代码 100 次,但我不相信我正在这样做。所以这就是我的设置方式。
使用统一采样器创建片段着色器。
uniform sampler2D sampler;
创建 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
创建帧缓冲区
var frameBuffer = gl.createFramebuffer();
然后我通过将 html 图像上传到 texture0 并将 texture0 绑定到采样器来开始“2 遍处理”。
然后我绑定帧缓冲区并调用 drawArrays:
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture1, 0);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
为了清理,我解除了帧缓冲区的绑定:
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
编辑:
在我的代码中添加断点后,我发现在我绑定空帧缓冲区之前实际上并没有抛出错误。所以 drawArrays 调用不会导致错误,它绑定了空帧缓冲区之后将其关闭。
Chrome 自版本 83 开始对帧缓冲区和活动纹理反馈循环执行保守检查。这些检查可能过于保守,影响了实际允许的使用。
在这些新检查中 Chrome 似乎不允许将渲染目标绑定到任何纹理槽,即使该槽未被程序使用。
在你的 2 pass 渲染中你可能有类似的东西:
- 初始化渲染目标并创建指向帧缓冲区的纹理。
- 渲染到目标。
在 1 中,您可能需要使用 gl.bindTexture(gl.TEXTURE_2D, yourTexture) 绑定纹理,然后,在第 2 步之前,使用 gl.bindTexture(gl) 取消绑定纹理.TEXTURE_2D, 空);否则 Chrome 将失败,因为渲染目标被绑定为纹理,即使该纹理未被程序采样。
我有一个 webgl 项目设置,它使用 2 pass 渲染在纹理上创建效果。
一切正常,直到最近 chrome 开始抛出此错误:
[.WebGL-0000020DB7FB7E40] GL_INVALID_OPERATION: Feedback loop formed between Framebuffer and active Texture.
虽然我没有更改我的代码,但这种情况才刚刚开始发生,所以我猜是新的更新导致了这种情况。
我在 SO 上找到
然而,我已经梳理了我的代码 100 次,但我不相信我正在这样做。所以这就是我的设置方式。
使用统一采样器创建片段着色器。
uniform sampler2D sampler;
创建 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
创建帧缓冲区
var frameBuffer = gl.createFramebuffer();
然后我通过将 html 图像上传到 texture0 并将 texture0 绑定到采样器来开始“2 遍处理”。
然后我绑定帧缓冲区并调用 drawArrays:
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture1, 0);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
为了清理,我解除了帧缓冲区的绑定:
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
编辑:
在我的代码中添加断点后,我发现在我绑定空帧缓冲区之前实际上并没有抛出错误。所以 drawArrays 调用不会导致错误,它绑定了空帧缓冲区之后将其关闭。
Chrome 自版本 83 开始对帧缓冲区和活动纹理反馈循环执行保守检查。这些检查可能过于保守,影响了实际允许的使用。
在这些新检查中 Chrome 似乎不允许将渲染目标绑定到任何纹理槽,即使该槽未被程序使用。
在你的 2 pass 渲染中你可能有类似的东西:
- 初始化渲染目标并创建指向帧缓冲区的纹理。
- 渲染到目标。
在 1 中,您可能需要使用 gl.bindTexture(gl.TEXTURE_2D, yourTexture) 绑定纹理,然后,在第 2 步之前,使用 gl.bindTexture(gl) 取消绑定纹理.TEXTURE_2D, 空);否则 Chrome 将失败,因为渲染目标被绑定为纹理,即使该纹理未被程序采样。