- juejin.cn/post/696543…
- juejin.cn/post/696440…
帧缓存/帧缓冲区(FBO FrameBufferObject)
- 帧缓冲区并不是实际存储数据的地方,实际存储图像数据数据的对象就是纹理(Texture)和渲染缓冲区(RenderBuffer)。
- 在帧缓冲区中可以附着3种类型的附着,颜色附着(ColorAttachment)|深度附着(DepthAttachment)|模板附着(StencilAttachment)。这三种附着对应的存储区域也被称为颜色缓冲区(ColorBuffer)|深度缓冲区(DepthBuffer)|模板缓冲区(StencilBuffer)。
颜色缓冲区(比深度缓存精度更高)
- 16位:RGB565,红色5位,绿色6位,蓝色5位,不保存透明通道(之所以绿色多1位是因为人眼对绿色更加敏感);
- 24位:RGB888,红色8位,绿色8位,蓝色8位,不保存透明通道;
- 32位:RGBA8888,红色8位,绿色8位,蓝色8位,透明通道8位;
- 如果使用了多渲染目标(Multiple Render Targets)技术,那么颜色附着的数量可能会大于一。
深度缓冲区(深度缓存)
- 存储每个像素点的深度,用来决定是丢弃当前像素颜色还是保留,假设,新渲染的颜色在旧颜色的前面,那么就覆盖旧颜色,如果新颜色在旧颜色的后面(被遮挡了)则保留旧颜色。
模板缓冲区
- 用来控制颜色缓存某个位置的写入操作,常用来处理阴影。
FrameBufferObject生成 方式一
var fbo = initFramebufferObject(gl);
//texture depthBuffer 返回fbo
function initFramebufferObject(gl) {
// texture 后面拿来用的
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture); // Bind the object to target
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, OFFSCREEN_WIDTH, OFFSCREEN_HEIGHT, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
// Renderbuffer 用来渲染的
var depthBuffer = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer); // Bind the object to target
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, OFFSCREEN_WIDTH, OFFSCREEN_HEIGHT);
//Framebuffer 有个有点展示的意思
var framebuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
framebuffer.texture = texture; // Store the texture object
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); //帧缓冲区 对应贴图
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthBuffer); //帧缓冲区 对应渲染缓冲区
return framebuffer;
}
FrameBufferObject使用
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); // Change the drawing destination to FBO
gl.viewport(0, 0, OFFSCREEN_HEIGHT, OFFSCREEN_HEIGHT); // Set view port for FBO
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); // Clear FBO
gl.useProgram(shadowProgram); // Set shaders for generating a shadow map
drawTriangle(gl, shadowProgram, triangle, currentAngle, viewProjMatrixFromLight);
drawPlane(gl, shadowProgram, plane, viewProjMatrixFromLight);
gl.bindFramebuffer(gl.FRAMEBUFFER, null); // Change the drawing destination to color buffer
gl.viewport(0, 0, canvas.width, canvas.height);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); // Clear color and depth buffer
gl.useProgram(normalProgram); // Set the shader for regular drawing
gl.uniform1i(normalProgram.u_ShadowMap, 0); // Pass 0 because gl.TEXTURE0 is enabled�る
drawTriangle(gl, normalProgram, triangle, currentAngle, viewProjMatrix);
gl.uniformMatrix4fv(normalProgram.u_MvpMatrixFromLight, false, mvpMatrixFromLight_p.elements);
drawPlane(gl, normalProgram, plane, viewProjMatrix);
FrameBufferObject生成 方式二 WebGL2
const whCube = 512;
brdfLUTTexture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, brdfLUTTexture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RG16F, whCube, whCube, 0, gl.RG, gl.FLOAT, new Float32Array(whCube * whCube * 2), 0);
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.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
let captureRBO = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, captureRBO);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT24, whCube, whCube);
let captureFBO = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, captureFBO);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, brdfLUTTexture, 0);
gl.viewport(0, 0, whCube, whCube);
brdfShader.use(gl);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
renderQuad();
FrameBufferObject使用
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
textureShader.use(gl);
textureShader.setInt(gl, "ourTexture", 0);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, brdfLUTTexture);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
renderQuad();
发表评论
还没有评论,快来抢沙发吧!