高级渲染技术
帧缓冲对象(FBO)
帧缓冲对象允许将渲染结果输出到纹理,而不是屏幕。
JAVASCRIPT1function createFramebuffer(gl, width, height) { 2 // 创建纹理 3 const texture = gl.createTexture(); 4 gl.bindTexture(gl.TEXTURE_2D, texture); 5 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); 6 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); 7 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 8 gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 9 10 // 创建渲染缓冲(用于深度测试) 11 const depthBuffer = gl.createRenderbuffer(); 12 gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer); 13 gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height); 14 15 // 创建帧缓冲 16 const framebuffer = gl.createFramebuffer(); 17 gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); 18 gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); 19 gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthBuffer); 20 21 gl.bindFramebuffer(gl.FRAMEBUFFER, null); 22 23 return { framebuffer, texture }; 24}
后期处理效果
模糊效果
GLSL1precision mediump float; 2uniform sampler2D uTexture; 3uniform vec2 uTextureSize; 4varying vec2 vTexCoord; 5 6void main() { 7 vec2 onePixel = vec2(1.0) / uTextureSize; 8 vec4 color = vec4(0.0); 9 10 // 3x3 高斯模糊 11 float kernel[9]; 12 kernel[0] = 0.045; kernel[1] = 0.122; kernel[2] = 0.045; 13 kernel[3] = 0.122; kernel[4] = 0.332; kernel[5] = 0.122; 14 kernel[6] = 0.045; kernel[7] = 0.122; kernel[8] = 0.045; 15 16 for (int i = 0; i < 3; i++) { 17 for (int j = 0; j < 3; j++) { 18 vec2 offset = vec2(float(i-1), float(j-1)) * onePixel; 19 color += texture2D(uTexture, vTexCoord + offset) * kernel[i*3+j]; 20 } 21 } 22 23 gl_FragColor = color; 24}
阴影映射
JAVASCRIPT1// 1. 从光源视角渲染深度图 2function renderShadowMap(gl, shadowProgram, objects, lightMatrix) { 3 gl.useProgram(shadowProgram); 4 gl.uniformMatrix4fv(uLightMatrix, false, lightMatrix); 5 6 // 绑定阴影贴图FBO 7 gl.bindFramebuffer(gl.FRAMEBUFFER, shadowFramebuffer); 8 gl.viewport(0, 0, shadowMapSize, shadowMapSize); 9 gl.clear(gl.DEPTH_BUFFER_BIT); 10 11 // 渲染场景(仅深度) 12 objects.forEach(obj => renderObjectDepth(obj)); 13} 14 15// 2. 正常渲染,使用阴影贴图 16function renderSceneWithShadows(gl, program, objects, cameraMatrix, shadowTexture) { 17 gl.useProgram(program); 18 gl.uniformMatrix4fv(uCameraMatrix, false, cameraMatrix); 19 gl.uniform1i(uShadowMap, 0); 20 21 gl.activeTexture(gl.TEXTURE0); 22 gl.bindTexture(gl.TEXTURE_2D, shadowTexture); 23 24 objects.forEach(obj => renderObject(obj)); 25}