【发布时间】:2021-11-27 06:03:38
【问题描述】:
我完全不了解帧缓冲区的这种情况。请看以下内容:
class Shader {
constructor(cvs, dim) {
cvs.width = dim[0];
cvs.height = dim[1];
this.gl = twgl.getContext(cvs);
this.bfi = twgl.createBufferInfoFromArrays(this.gl, {
a_position: {
numComponents: 2,
data: [-1, -1, -1, 3, 3, -1]
}
});
this.pgi = {
write: twgl.createProgramInfo(this.gl, ["vs", "fs_write"]),
read: twgl.createProgramInfo(this.gl, ["vs", "fs_read"])
};
this.fbs = Array(2)
.fill()
.map(() => twgl.createFramebufferInfo(this.gl));
this.gl.useProgram(this.pgi.write.program);
twgl.setUniforms(this.pgi.write, {
u_resolution: dim
});
this.gl.useProgram(this.pgi.read.program);
twgl.setUniforms(this.pgi.read, {
u_framebuffer: this.fbs[0].attachments[0],
u_resolution: dim
});
}
ldImg(src, handler) {
this.gl.useProgram(this.pgi.write.program);
twgl.setUniforms(this.pgi.write, {
u_texture: twgl.createTexture(
this.gl,
{ src },
handler
)
});
}
frame() {
twgl.bindFramebufferInfo(this.gl, this.fbs[0]);
this.gl.useProgram(this.pgi.write.program);
twgl.setBuffersAndAttributes(this.gl, this.pgi.write, this.bfi);
twgl.drawBufferInfo(this.gl, this.bfi);
twgl.bindFramebufferInfo(this.gl, null);
this.gl.useProgram(this.pgi.read.program);
// twgl.setUniforms(this.pgi.read, {
// u_framebuffer: this.fbs[0].attachments[0]
// });
twgl.setBuffersAndAttributes(this.gl, this.pgi.read, this.bfi);
twgl.drawBufferInfo(this.gl, this.bfi);
// this.fbs = [this.fbs[1], this.fbs[0]];
}
}
(function main() {
const dim = [512, 512];
const shr = new Shader(document.querySelector("canvas"), dim);
shr.ldImg("https://assets.codepen.io/854924/ad.png", frame);
function frame(ms) {
shr.frame();
window.requestAnimationFrame(frame);
}
})();
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>
<script id="vs" type="x-shader/x-vertex">
attribute vec4 a_position;
void main() {
gl_Position = a_position;
}
</script>
<script id="fs_write" type="x-shader/x-fragment">
precision highp float;
uniform vec2 u_resolution;
uniform sampler2D u_texture;
void main() {
gl_FragColor = texture2D(u_texture, (gl_FragCoord.xy + 1.0) / u_resolution);
}
</script>
<script id="fs_read" type="x-shader/x-fragment">
precision highp float;
uniform sampler2D u_framebuffer;
uniform vec2 u_resolution;
void main() {
gl_FragColor = vec4(
1.0 - texture2D(u_framebuffer, gl_FragCoord.xy / u_resolution).rgb,
1.0
);
}
</script>
<canvas></canvas>
我试图让事情尽可能简单。有两个程序,write 和read,其中write 从纹理中读取,平移一个像素并写入输出。然后read 从帧缓冲区读取,反转图像并写入输出。在当前情况下,我让write 渲染到帧缓冲区,read 渲染到屏幕。一切正常。
现在,如果我取消注释 JS 中的第一行注释,我会收到错误 Feedback loop formed between Framebuffer and active Texture,这很奇怪,因为 read 中的统一 u_framebuffer 始终设置为相同的帧缓冲区,我只是重新绑定统一已经绑定。它也不应该创建反馈循环,因为write 没有绑定帧缓冲区,而read 不尝试渲染到帧缓冲区。
如果我取消注释 JS 中的两条注释行,以便帧缓冲区在每一帧都被切换,我可以看到纹理在屏幕上“行走”。所以这显然是一个反馈循环(一个像素偏移被累积),但我看不出它来自哪里。 write 只是从纹理中读取,它应该是绝对静态的,但不知何故它似乎消耗了自己的输出。
我在这里很迷茫,要么制服和帧缓冲区中有一些我根本不理解的逻辑,要么是我以前从未遇到过的错误?
【问题讨论】:
标签: webgl framebuffer feedback twgl.js