我正在创建一个简单的WebGL 3D引擎,现在我正在尝试添加一些后期处理效果。 我这样做:我使用帧缓冲区绘制场景并渲染到纹理,而不是将纹理传递给我的简单后处理着色器,渲染到实际的物理屏幕(我遵循openGL后处理教程:{ {3}})。
创建帧缓冲区:
// texture
gl.activeTexture(gl.TEXTURE0);
frameBufferTexture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, frameBufferTexture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.viewportWidth, gl.viewportHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.bindTexture(gl.TEXTURE_2D, null);
// depth buffer
frameBufferDepth = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, frameBufferDepth);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, gl.viewportWidth, gl.viewportHeight);
// framebuffer to link everything together
frameBufferObject = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBufferObject);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, frameBufferTexture, 0);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, frameBufferDepth);
// check status
var success = (gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE);
if (success)
console.log('post processing frame object created');
else
throw "could not create post processing frame: " + gl.checkFramebufferStatus(gl.FRAMEBUFFER);
// vertices
var fbo_vertices = [
-1.0, -1.0,
1.0, -1.0,
-1.0, 1.0,
1.0, 1.0
];
frameBufferVertices = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, frameBufferVertices);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(fbo_vertices), gl.STATIC_DRAW);
然后,当我画出场景时,我打电话给:
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBufferObject);
定位帧缓冲区
然后我最终使用基本着色器将纹理渲染到屏幕上(除了纹理点之外什么都不做):
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clearDepth(1.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, frameBufferTexture);
gl.uniform1i(shaderProgram.fbo_texture, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, frameBufferVertices);
gl.vertexAttribPointer(shaderProgram.fbo_vertex, 2, gl.FLOAT, false, 0, 0);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
此时一切正常,现在我的想法是使用多个着色器(每个着色器使用不同的程序),共享相同的帧缓冲区,因此每个着色器都会输入纹理并写入它。
我尝试在for循环中使用多个着色器和调用(对于每个着色器):
gl.useProgram(postProcessingProgram);
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBufferObject);
gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clearDepth(1.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, frameBufferTexture);
gl.uniform1i(postProcessingProgram.basic_texture, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, frameBufferVertices);
gl.vertexAttribPointer(postProcessingProgram.fbo_vertex, 2, gl.FLOAT, false, 0, 0);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
除了渲染到物理屏幕的最后一个基本着色器
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
屏幕完全是黑色,但我没有收到任何错误或警告。即使我使用相同的基本着色器两次也不起作用。
我的问题是:对多个着色器使用相同的帧缓冲区是否正确?如果我使用多个帧缓冲区,我如何共享相同的纹理来执行连续的步骤?