OpenGL多帧缓冲区渲染

时间:2013-12-25 00:05:18

标签: javascript opengl-es webgl

我正在创建一个简单的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);

屏幕完全是黑色,但我没有收到任何错误或警告。即使我使用相同的基本着色器两次也不起作用。

我的问题是:对多个着色器使用相同的帧缓冲区是否正确?如果我使用多个帧缓冲区,我如何共享相同的纹理来执行连续的步骤?

0 个答案:

没有答案