<< All versions
Skill v1.0.1
currentAutomated scan100/100cloudai-x/threejs-skills/threejs-postprocessing
1 files
──Details
PublishedMay 15, 2026 at 02:04 AM
Content Hashsha256:570b86434c30ad9b...
Git SHAb1c623076c66
Bump Typepatch
──Files
Files (1 file, 14.1 KB)
SKILL.md14.1 KBactive
SKILL.md · 604 lines · 14.1 KB
version: "1.0.1" name: threejs-postprocessing description: Three.js post-processing - EffectComposer, bloom, DOF, screen effects. Use when adding visual effects, color grading, blur, glow, or creating custom screen-space shaders.
Three.js Post-Processing
Quick Start
javascript
import * as THREE from "three";import { EffectComposer } from "three/addons/postprocessing/EffectComposer.js";import { RenderPass } from "three/addons/postprocessing/RenderPass.js";import { UnrealBloomPass } from "three/addons/postprocessing/UnrealBloomPass.js";// Setup composerconst composer = new EffectComposer(renderer);// Render sceneconst renderPass = new RenderPass(scene, camera);composer.addPass(renderPass);// Add bloomconst bloomPass = new UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight),1.5, // strength0.4, // radius0.85, // threshold);composer.addPass(bloomPass);// Animation loop - use composer instead of rendererfunction animate() {requestAnimationFrame(animate);composer.render(); // NOT renderer.render()}
EffectComposer Setup
javascript
import { EffectComposer } from "three/addons/postprocessing/EffectComposer.js";import { RenderPass } from "three/addons/postprocessing/RenderPass.js";const composer = new EffectComposer(renderer);// First pass: render sceneconst renderPass = new RenderPass(scene, camera);composer.addPass(renderPass);// Add more passes...composer.addPass(effectPass);// Last pass should render to screeneffectPass.renderToScreen = true; // Default for last pass// Handle resizefunction onResize() {const width = window.innerWidth;const height = window.innerHeight;camera.aspect = width / height;camera.updateProjectionMatrix();renderer.setSize(width, height);composer.setSize(width, height);}
Common Effects
Bloom (Glow)
javascript
import { UnrealBloomPass } from "three/addons/postprocessing/UnrealBloomPass.js";const bloomPass = new UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight),1.5, // strength - intensity of glow0.4, // radius - spread of glow0.85, // threshold - brightness threshold);composer.addPass(bloomPass);// Adjust at runtimebloomPass.strength = 2.0;bloomPass.threshold = 0.5;bloomPass.radius = 0.8;
Selective Bloom
Apply bloom only to specific objects.
javascript
import { UnrealBloomPass } from "three/addons/postprocessing/UnrealBloomPass.js";import { ShaderPass } from "three/addons/postprocessing/ShaderPass.js";// Layer setupconst BLOOM_LAYER = 1;const bloomLayer = new THREE.Layers();bloomLayer.set(BLOOM_LAYER);// Mark objects to bloomglowingMesh.layers.enable(BLOOM_LAYER);// Dark material for non-blooming objectsconst darkMaterial = new THREE.MeshBasicMaterial({ color: 0x000000 });const materials = {};function darkenNonBloomed(obj) {if (obj.isMesh && !bloomLayer.test(obj.layers)) {materials[obj.uuid] = obj.material;obj.material = darkMaterial;}}function restoreMaterial(obj) {if (materials[obj.uuid]) {obj.material = materials[obj.uuid];delete materials[obj.uuid];}}// Custom render loopfunction render() {// Render bloom passscene.traverse(darkenNonBloomed);composer.render();scene.traverse(restoreMaterial);// Render final scene over bloomrenderer.render(scene, camera);}
FXAA (Anti-Aliasing)
javascript
import { ShaderPass } from "three/addons/postprocessing/ShaderPass.js";import { FXAAShader } from "three/addons/shaders/FXAAShader.js";const fxaaPass = new ShaderPass(FXAAShader);fxaaPass.material.uniforms["resolution"].value.set(1 / window.innerWidth,1 / window.innerHeight,);composer.addPass(fxaaPass);// Update on resizefunction onResize() {fxaaPass.material.uniforms["resolution"].value.set(1 / window.innerWidth,1 / window.innerHeight,);}
SMAA (Better Anti-Aliasing)
javascript
import { SMAAPass } from "three/addons/postprocessing/SMAAPass.js";const smaaPass = new SMAAPass(window.innerWidth * renderer.getPixelRatio(),window.innerHeight * renderer.getPixelRatio(),);composer.addPass(smaaPass);
SSAO (Ambient Occlusion)
javascript
import { SSAOPass } from "three/addons/postprocessing/SSAOPass.js";const ssaoPass = new SSAOPass(scene,camera,window.innerWidth,window.innerHeight,);ssaoPass.kernelRadius = 16;ssaoPass.minDistance = 0.005;ssaoPass.maxDistance = 0.1;composer.addPass(ssaoPass);// Output modesssaoPass.output = SSAOPass.OUTPUT.Default;// SSAOPass.OUTPUT.Default - Final composited output// SSAOPass.OUTPUT.SSAO - Just the AO// SSAOPass.OUTPUT.Blur - Blurred AO// SSAOPass.OUTPUT.Depth - Depth buffer// SSAOPass.OUTPUT.Normal - Normal buffer
Depth of Field (DOF)
javascript
import { BokehPass } from "three/addons/postprocessing/BokehPass.js";const bokehPass = new BokehPass(scene, camera, {focus: 10.0, // Focus distanceaperture: 0.025, // Aperture (smaller = more DOF)maxblur: 0.01, // Max blur amount});composer.addPass(bokehPass);// Update focus dynamicallybokehPass.uniforms["focus"].value = distanceToTarget;
Film Grain
javascript
import { FilmPass } from "three/addons/postprocessing/FilmPass.js";const filmPass = new FilmPass(0.35, // noise intensity0.5, // scanline intensity648, // scanline countfalse, // grayscale);composer.addPass(filmPass);
Vignette
javascript
import { ShaderPass } from "three/addons/postprocessing/ShaderPass.js";import { VignetteShader } from "three/addons/shaders/VignetteShader.js";const vignettePass = new ShaderPass(VignetteShader);vignettePass.uniforms["offset"].value = 1.0; // Vignette sizevignettePass.uniforms["darkness"].value = 1.0; // Vignette intensitycomposer.addPass(vignettePass);
Color Correction
javascript
import { ShaderPass } from "three/addons/postprocessing/ShaderPass.js";import { ColorCorrectionShader } from "three/addons/shaders/ColorCorrectionShader.js";const colorPass = new ShaderPass(ColorCorrectionShader);colorPass.uniforms["powRGB"].value = new THREE.Vector3(1.2, 1.2, 1.2); // PowercolorPass.uniforms["mulRGB"].value = new THREE.Vector3(1.0, 1.0, 1.0); // Multiplycomposer.addPass(colorPass);
Gamma Correction
javascript
import { GammaCorrectionShader } from "three/addons/shaders/GammaCorrectionShader.js";const gammaPass = new ShaderPass(GammaCorrectionShader);composer.addPass(gammaPass);
Pixelation
javascript
import { RenderPixelatedPass } from "three/addons/postprocessing/RenderPixelatedPass.js";const pixelPass = new RenderPixelatedPass(6, scene, camera); // 6 = pixel sizecomposer.addPass(pixelPass);
Glitch Effect
javascript
import { GlitchPass } from "three/addons/postprocessing/GlitchPass.js";const glitchPass = new GlitchPass();glitchPass.goWild = false; // Continuous glitchingcomposer.addPass(glitchPass);
Halftone
javascript
import { HalftonePass } from "three/addons/postprocessing/HalftonePass.js";const halftonePass = new HalftonePass(window.innerWidth, window.innerHeight, {shape: 1, // 1 = dot, 2 = ellipse, 3 = line, 4 = squareradius: 4, // Dot sizerotateR: Math.PI / 12,rotateB: (Math.PI / 12) * 2,rotateG: (Math.PI / 12) * 3,scatter: 0,blending: 1,blendingMode: 1,greyscale: false,});composer.addPass(halftonePass);
Outline
javascript
import { OutlinePass } from "three/addons/postprocessing/OutlinePass.js";const outlinePass = new OutlinePass(new THREE.Vector2(window.innerWidth, window.innerHeight),scene,camera,);outlinePass.edgeStrength = 3;outlinePass.edgeGlow = 0;outlinePass.edgeThickness = 1;outlinePass.pulsePeriod = 0;outlinePass.visibleEdgeColor.set(0xffffff);outlinePass.hiddenEdgeColor.set(0x190a05);// Select objects to outlineoutlinePass.selectedObjects = [mesh1, mesh2];composer.addPass(outlinePass);
Custom ShaderPass
Create your own post-processing effects.
javascript
import { ShaderPass } from "three/addons/postprocessing/ShaderPass.js";const CustomShader = {uniforms: {tDiffuse: { value: null }, // Required: input texturetime: { value: 0 },intensity: { value: 1.0 },},vertexShader: `varying vec2 vUv;void main() {vUv = uv;gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);}`,fragmentShader: `uniform sampler2D tDiffuse;uniform float time;uniform float intensity;varying vec2 vUv;void main() {vec2 uv = vUv;// Wave distortionuv.x += sin(uv.y * 10.0 + time) * 0.01 * intensity;vec4 color = texture2D(tDiffuse, uv);gl_FragColor = color;}`,};const customPass = new ShaderPass(CustomShader);composer.addPass(customPass);// Update in animation loopcustomPass.uniforms.time.value = clock.getElapsedTime();
Invert Colors Shader
javascript
const InvertShader = {uniforms: {tDiffuse: { value: null },},vertexShader: `varying vec2 vUv;void main() {vUv = uv;gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);}`,fragmentShader: `uniform sampler2D tDiffuse;varying vec2 vUv;void main() {vec4 color = texture2D(tDiffuse, vUv);gl_FragColor = vec4(1.0 - color.rgb, color.a);}`,};
Chromatic Aberration
javascript
const ChromaticAberrationShader = {uniforms: {tDiffuse: { value: null },amount: { value: 0.005 },},vertexShader: `varying vec2 vUv;void main() {vUv = uv;gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);}`,fragmentShader: `uniform sampler2D tDiffuse;uniform float amount;varying vec2 vUv;void main() {vec2 dir = vUv - 0.5;float dist = length(dir);float r = texture2D(tDiffuse, vUv - dir * amount * dist).r;float g = texture2D(tDiffuse, vUv).g;float b = texture2D(tDiffuse, vUv + dir * amount * dist).b;gl_FragColor = vec4(r, g, b, 1.0);}`,};
Combining Multiple Effects
javascript
import { EffectComposer } from "three/addons/postprocessing/EffectComposer.js";import { RenderPass } from "three/addons/postprocessing/RenderPass.js";import { UnrealBloomPass } from "three/addons/postprocessing/UnrealBloomPass.js";import { ShaderPass } from "three/addons/postprocessing/ShaderPass.js";import { FXAAShader } from "three/addons/shaders/FXAAShader.js";import { VignetteShader } from "three/addons/shaders/VignetteShader.js";import { GammaCorrectionShader } from "three/addons/shaders/GammaCorrectionShader.js";const composer = new EffectComposer(renderer);// 1. Render scenecomposer.addPass(new RenderPass(scene, camera));// 2. Bloomconst bloomPass = new UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight),0.5,0.4,0.85,);composer.addPass(bloomPass);// 3. Vignetteconst vignettePass = new ShaderPass(VignetteShader);vignettePass.uniforms["offset"].value = 0.95;vignettePass.uniforms["darkness"].value = 1.0;composer.addPass(vignettePass);// 4. Gamma correctioncomposer.addPass(new ShaderPass(GammaCorrectionShader));// 5. Anti-aliasing (always last before output)const fxaaPass = new ShaderPass(FXAAShader);fxaaPass.uniforms["resolution"].value.set(1 / window.innerWidth,1 / window.innerHeight,);composer.addPass(fxaaPass);
Render to Texture
javascript
// Create render targetconst renderTarget = new THREE.WebGLRenderTarget(512, 512);// Render scene to targetrenderer.setRenderTarget(renderTarget);renderer.render(scene, camera);renderer.setRenderTarget(null);// Use textureconst texture = renderTarget.texture;otherMaterial.map = texture;
Multi-Pass Rendering
javascript
// Multiple composers for different scenes/layersconst bgComposer = new EffectComposer(renderer);bgComposer.addPass(new RenderPass(bgScene, camera));const fgComposer = new EffectComposer(renderer);fgComposer.addPass(new RenderPass(fgScene, camera));fgComposer.addPass(bloomPass);// Combine in render loopfunction animate() {// Render background without clearingrenderer.autoClear = false;renderer.clear();bgComposer.render();// Render foreground over itrenderer.clearDepth();fgComposer.render();}
WebGPU Post-Processing (Three.js r150+)
javascript
import { postProcessing } from "three/addons/nodes/Nodes.js";import { pass, bloom, dof } from "three/addons/nodes/Nodes.js";// Using node-based systemconst scenePass = pass(scene, camera);const bloomNode = bloom(scenePass, 0.5, 0.4, 0.85);const postProcessing = new THREE.PostProcessing(renderer);postProcessing.outputNode = bloomNode;// Renderfunction animate() {postProcessing.render();}
Performance Tips
- Limit passes: Each pass adds a full-screen render
- Lower resolution: Use smaller render targets for blur passes
- Disable unused effects: Toggle passes on/off
- Use FXAA over MSAA: Less expensive anti-aliasing
- Profile with DevTools: Check GPU usage
javascript
// Disable passbloomPass.enabled = false;// Reduce bloom resolutionconst bloomPass = new UnrealBloomPass(new THREE.Vector2(window.innerWidth / 2, window.innerHeight / 2),strength,radius,threshold,);// Only apply effects in high-performance scenariosconst isMobile = /iPhone|iPad|Android/i.test(navigator.userAgent);if (!isMobile) {composer.addPass(expensivePass);}
Handle Resize
javascript
function onWindowResize() {const width = window.innerWidth;const height = window.innerHeight;const pixelRatio = renderer.getPixelRatio();camera.aspect = width / height;camera.updateProjectionMatrix();renderer.setSize(width, height);composer.setSize(width, height);// Update pass-specific resolutionsif (fxaaPass) {fxaaPass.material.uniforms["resolution"].value.set(1 / (width * pixelRatio),1 / (height * pixelRatio),);}if (bloomPass) {bloomPass.resolution.set(width, height);}}window.addEventListener("resize", onWindowResize);
See Also
threejs-shaders- Custom shader developmentthreejs-textures- Render targetsthreejs-fundamentals- Renderer setup