【发布时间】:2020-09-16 08:46:40
【问题描述】:
我有一个 webgl 项目设置,它使用 2 次渲染在纹理上创建效果。
一切正常,直到最近 chrome 开始抛出此错误:
[.WebGL-0000020DB7FB7E40] GL_INVALID_OPERATION: Feedback loop formed between Framebuffer and active Texture.
即使我没有更改我的代码,这种情况才刚刚开始发生,所以我猜是新的更新导致了这种情况。
我在 SO 上找到 this answer,指出错误“在您从当前附加到帧缓冲区的纹理中读取时发生”。
但是我已经梳理了我的代码 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 pass处理”。
然后我绑定帧缓冲区并调用 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 调用不会导致错误,它会绑定空帧缓冲区,然后将其设置为关闭。
【问题讨论】:
-
您需要显示更多代码,但您发布的代码可能有反馈循环。您创建的最后一个纹理是 texture1,所以它仍然是绑定的。将其附加到帧缓冲区。然后你画。如果您的着色器使用纹理,它看起来肯定会同时尝试从纹理 1 读取和从纹理 1 写入。
-
也许我误解了它的工作原理,但我的着色器不能只从采样器中读取纹理。那么纹理0绑定到采样器我怎么能从纹理1中读取呢?我知道纹理 1 仍然是活动纹理,我认为它必须将它绑定到帧缓冲区。绑定后我应该让它“非活动”吗?
-
@gman,也请参阅我的编辑。不知道为什么,但似乎在绘制调用之后绑定空帧缓冲区是导致错误的原因。
-
我很确定这实际上是由绑定采样器跟踪的 libANGLE 实现损坏引起的。一旦纹理被绑定为采样器,即使它在之后未绑定,浏览器也会认为它正在被使用。该更改已实施in this commit,并且还有一些修复;它似乎在最新的 Canary 中工作。
-
投票结束。你还没有输入mininal-reproducable-example。请添加一个
标签: webgl