Post-processing renders the scene to a texture, then applies full-screen
shader passes to add bloom, depth of field, vignette, or any custom
effect. This tutorial builds the pipeline from scratch using
WebGLRenderTarget and a fullscreen quad — no external
post-processing libraries needed.
1Render scene to a texture
import * as THREE from
'https://cdn.jsdelivr.net/npm/three@0.160/build/three.module.js';
function makeRT(w, h) { return new THREE.WebGLRenderTarget(w, h, {
minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format:
THREE.RGBAFormat, type: THREE.HalfFloatType, // HDR range for bloom
}); } let rt = makeRT(innerWidth, innerHeight); // In render loop:
renderer.setRenderTarget(rt); // render TO texture
renderer.render(scene, camera); renderer.setRenderTarget(null); //
reset to screen framebuffer // rt.texture is now the scene as sampled
image
Use HalfFloatType render targets for HDR bloom — values
above 1.0 encode over-bright areas. Regular
UnsignedByteType clamps everything to [0,1] and loses the
bloom signal.
2Fullscreen quad setup
// A plane covering the entire NDC cube const quadGeo = new
THREE.PlaneGeometry(2, 2); const quadCam = new
THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1); const quadScene = new
THREE.Scene(); // The post-process material reads the scene texture
const postMat = new THREE.ShaderMaterial({ uniforms: { u_tex: { value:
null }, u_res: { value: new THREE.Vector2(innerWidth, innerHeight) },
u_time: { value: 0 }, }, vertexShader: ` varying vec2 vUv; void main()
{ vUv = uv; gl_Position = vec4(position, 1.0); } `, fragmentShader: `
uniform sampler2D u_tex; varying vec2 vUv; void main() { gl_FragColor
= texture2D(u_tex, vUv); } `, }); const quad = new THREE.Mesh(quadGeo,
postMat); quadScene.add(quad);
The bloom pass runs at half resolution to save bandwidth. This is a
simple 4:1 downsample — for higher quality use a mobile Kawase or dual
Kawase blur which gives Gaussian results at fewer samples.
Frequently Asked Questions
What will I learn in this tutorial?
Use Three.js WebGLRenderTarget to implement bloom, depth of field, chromatic aberration, and custom post-processing passes without libraries.
What topics are covered in this tutorial?
This tutorial covers: Render scene to a texture, Fullscreen quad setup, Bloom: threshold + Gaussian blur, Chromatic aberration, Vignette and scanlines, Multi-pass pipeline.
What tools and technologies does this tutorial use?
This tutorial uses Three.js, WebGLRenderTarget, GLSL, Post-processing.
How long does this tutorial take?
This tutorial takes approximately 50 minutes to complete.
What prerequisites do I need before starting?
This is a Intermediate-level tutorial — no special preparation beyond basic JavaScript is assumed.