- Juejin. Cn/post / 696543…
- Juejin. Cn/post / 696440…
Frame Cache/FrameBuffer (FBO FrameBufferObject)
- Frame buffer (FBO), Off-screen render,renderTarget
- To export images without rendering the model, use off-screen rendering
- ThreeJS,renderTarget can clearcolor, can overrideMaterial
- The frame buffer is not where the actual data is stored. The objects that actually store the image data are the Texture and the RenderBuffer.
- In the frame buffer can be attached to three types of adhesion, color adhesion (ColorAttachment) adhesion (DepthAttachment) | | depth template attached (StencilAttachment). These three attached to the corresponding storage area is also known as color buffer (ColorBuffer) (DepthBuffer) | | depth buffer stencil buffer (StencilBuffer).
Color buffer (more accurate than depth buffer)
- DEPTH_COMPONENT16: 16 bits: RGB565, red 5 bits, green 6 bits, blue 5 bits, do not save transparent channel (the reason why the green 1 bit more because the human eye is more sensitive to green);
- DEPTH_COMPONENT24: 24 bits: RGB888, red 8 bits, green 8 bits, blue 8 bits, do not save transparent channel;
- DEPTH_COMPONENT32: 32-bit: RGBA8888, red 8 bits, Green 8 bits, blue 8 bits, transparent channel 8 bits;
- If Multiple Render Targets are used, the number of color attachments may be greater than one.
Depth buffer (depth cache)
- Store the depth of each pixel to determine whether to discard the current pixel color or keep it, assuming that the newly rendered color is in front of the old color, then overwrite the old color, if the new color is behind the old color (blocked).
Template buffer
- Used to control writing to a location in the color cache, often for shadows.
FrameBufferObject Generation method 1
var fbo = initFramebufferObject(gl);
//texture depthBuffer returns fBO
function initFramebufferObject(gl) {
// Texture is the texture to use
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 is used for rendering
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);
// The Framebuffer is a bit of a demonstration
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); // The frame buffer corresponds to the map
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthBuffer); // Frame buffer corresponds to render buffer
return framebuffer;
}
Copy the code
FrameBufferObject use
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);
Copy the code
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 enableda �™ a and panel
drawTriangle(gl, normalProgram, triangle, currentAngle, viewProjMatrix);
gl.uniformMatrix4fv(normalProgram.u_MvpMatrixFromLight, false, mvpMatrixFromLight_p.elements);
drawPlane(gl, normalProgram, plane, viewProjMatrix);
Copy the code
FrameBufferObject Generation mode 2 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();
Copy the code
FrameBufferObject use
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();
Copy the code