Skip to main content 首页 创作者 afovea game-dev-skills threejs-postprocessing
threejs-postprocessing Three.js post-processing with EffectComposer — RenderPass, UnrealBloomPass, SSAOPass, BokehPass, FilmPass, OutlinePass, FXAA/SMAA anti-aliasing, custom ShaderPass, multi-pass composition, selective bloom, resize handling, and performance. Use when adding bloom, depth-of-field, ambient occlusion, outlines, colour grading, or any screen-space effect to a Three.js scene. Adapted from CloudAI-X/threejs-skills (MIT).
跳到安装 Skills Marketplace 发现并探索由社区构建的 Agent Skills
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/afovea/game-dev-skills --skill threejs-postprocessing命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
下载 Zip 下载中... 同仓库更多 Skills Art Director persona for visual style, pillars, art bible, cross-discipline visual consistency, art critique, and art QA. Use when a task needs visual direction, style enforcement, or cohesion across concept, environment, character, VFX, and lighting.
Audio Director persona for sound design, music direction, mix, audio implementation patterns, and audio pipeline. Use when a task needs reasoning about audio intent, audio-mechanic integration, mix balance, or the audio toolchain.
Post-pipeline cleanup and verification pass for game-development work. Regenerate / re-bake any derived content, rebuild the project, verify the editor / engine opens cleanly, run automated test suites, take a perf snapshot against budgets, and confirm save / network / cert / pipeline surfaces are untouched (or correctly versioned) against the pre-run baseline.
name threejs-postprocessing description Three.js post-processing with EffectComposer — RenderPass, UnrealBloomPass, SSAOPass, BokehPass, FilmPass, OutlinePass, FXAA/SMAA anti-aliasing, custom ShaderPass, multi-pass composition, selective bloom, resize handling, and performance. Use when adding bloom, depth-of-field, ambient occlusion, outlines, colour grading, or any screen-space effect to a Three.js scene. Adapted from CloudAI-X/threejs-skills (MIT). license MIT compatibility Portable reference skill for agents that support markdown skills or prompt files. Works best alongside project Three.js source files and Chrome DevTools GPU profiling. disable-model-invocation true metadata {"owner":"game-delivery","version":"2.0.0","language":"en-GB","category":"web-rendering","upstream_references":["https://github.com/CloudAI-X/threejs-skills (MIT — see NOTICE.md)"],"tags":["three-js","post-processing","effect-composer","bloom","ssao","depth-of-field","anti-aliasing","outline","shader-pass","screen-space-effects"],"intents":["effect-composition","bloom-setup","ambient-occlusion","depth-of-field","outline-effect","antialiasing-selection","custom-pass-authoring"],"output_types":["code-example","api-reference","pass-chain-plan"]}
Three.js Post-Processing
Quick Start
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' ;
const composer = new EffectComposer (renderer);
composer.addPass (new RenderPass (scene, camera));
composer.addPass (new UnrealBloomPass (
new THREE .Vector2 (window .innerWidth , window .innerHeight ),
0.5 ,
0.4 ,
0.85 ,
));
function animate ( ) {
requestAnimationFrame (animate);
composer.render ();
}
EffectComposer Setup
import { } ;
{ } ;
renderTarget = . (
. ,
. ,
{
: . ,
: . ,
: . ,
: ,
}
);
composer = (renderer, renderTarget);
composer. ( (scene, camera));
( ) {
composer. ( . , . );
composer. ( . ( . , ));
}
. ( , onResize);
EffectComposer
from
'three/addons/postprocessing/EffectComposer.js'
import
RenderPass
from
'three/addons/postprocessing/RenderPass.js'
const
new
THREE
WebGLRenderTarget
window
innerWidth
window
innerHeight
type
THREE
HalfFloatType
format
THREE
RGBAFormat
colorSpace
THREE
SRGBColorSpace
samples
4
const
new
EffectComposer
addPass
new
RenderPass
function
onResize
setSize
window
innerWidth
window
innerHeight
setPixelRatio
Math
min
window
devicePixelRatio
2
window
addEventListener
'resize'
Pass Reference
RenderPass — Required First Pass import { RenderPass } from 'three/addons/postprocessing/RenderPass.js' ;
const renderPass = new RenderPass (scene, camera);
renderPass.clearColor = new THREE .Color (0x000000 );
renderPass.clearAlpha = 1 ;
composer.addPass (renderPass);
UnrealBloomPass — Glow / Bloom import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js' ;
const bloom = new UnrealBloomPass (
new THREE .Vector2 (window .innerWidth , window .innerHeight ),
1.5 ,
0.4 ,
0.85 ,
);
bloom.enabled = true ;
composer.addPass (bloom);
bloom.strength = 1.0 ;
bloom.radius = 0.5 ;
bloom.threshold = 0.8 ;
SSAOPass — Screen-Space Ambient Occlusion import { SSAOPass } from 'three/addons/postprocessing/SSAOPass.js' ;
const ssao = new SSAOPass (scene, camera, window .innerWidth , window .innerHeight );
ssao.kernelRadius = 16 ;
ssao.minDistance = 0.005 ;
ssao.maxDistance = 0.1 ;
composer.addPass (ssao);
BokehPass — Depth of Field import { BokehPass } from 'three/addons/postprocessing/BokehPass.js' ;
const bokeh = new BokehPass (scene, camera, {
focus : 500.0 ,
aperture : 0.025 ,
maxblur : 0.01 ,
});
composer.addPass (bokeh);
bokeh.uniforms ['focus' ].value = focusDistance;
bokeh.uniforms ['aperture' ].value = apertureValue;
FilmPass — Film Grain and Scanlines import { FilmPass } from 'three/addons/postprocessing/FilmPass.js' ;
const film = new FilmPass (
0.35 ,
0.0 ,
648 ,
false
);
composer.addPass (film);
DotScreenPass — Pop-Art Halftone import { DotScreenPass } from 'three/addons/postprocessing/DotScreenPass.js' ;
const dotScreen = new DotScreenPass (
new THREE .Vector2 (0 , 0 ),
0.5 ,
0.8 ,
);
composer.addPass (dotScreen);
GlitchPass — Digital Glitch import { GlitchPass } from 'three/addons/postprocessing/GlitchPass.js' ;
const glitch = new GlitchPass ();
glitch.goWild = false ;
composer.addPass (glitch);
OutlinePass — Object Outlines import { OutlinePass } from 'three/addons/postprocessing/OutlinePass.js' ;
const outline = new OutlinePass (
new THREE .Vector2 (window .innerWidth , window .innerHeight ),
scene,
camera,
);
outline.edgeStrength = 3.0 ;
outline.edgeGlow = 0.5 ;
outline.edgeThickness = 1.0 ;
outline.visibleEdgeColor .set ('#ffffff' );
outline.hiddenEdgeColor .set ('#190a05' );
composer.addPass (outline);
outline.selectedObjects = [mesh1, mesh2];
outline.selectedObjects = [];
Anti-Aliasing MSAA built into the renderer is the simplest; post-process AA is needed when using a custom render target.
FXAA — Fast Approximate AA import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js' ;
import { FXAAShader } from 'three/addons/shaders/FXAAShader.js' ;
const fxaa = new ShaderPass (FXAAShader );
fxaa.material .uniforms ['resolution' ].value .x = 1 / (window .innerWidth * renderer.getPixelRatio ());
fxaa.material .uniforms ['resolution' ].value .y = 1 / (window .innerHeight * renderer.getPixelRatio ());
composer.addPass (fxaa);
function onResize ( ) {
fxaa.material .uniforms ['resolution' ].value .x = 1 / (window .innerWidth * renderer.getPixelRatio ());
fxaa.material .uniforms ['resolution' ].value .y = 1 / (window .innerHeight * renderer.getPixelRatio ());
}
SMAA — Sub-pixel Morphological AA (Higher Quality) import { SMAAPass } from 'three/addons/postprocessing/SMAAPass.js' ;
const smaa = new SMAAPass (
window .innerWidth * renderer.getPixelRatio (),
window .innerHeight * renderer.getPixelRatio (),
);
composer.addPass (smaa);
TAA — Temporal AA (Reduces Shimmer) import { TAARenderPass } from 'three/addons/postprocessing/TAARenderPass.js' ;
const taa = new TAARenderPass (scene, camera);
taa.sampleLevel = 2 ;
composer.addPass (taa);
Custom ShaderPass import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js' ;
const vignetteShader = {
uniforms : {
tDiffuse : { value : null },
uStrength : { value : 0.5 },
uOffset : { value : 1.2 },
},
vertexShader : `
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
` ,
fragmentShader : `
uniform sampler2D tDiffuse;
uniform float uStrength;
uniform float uOffset;
varying vec2 vUv;
void main() {
vec4 colour = texture2D(tDiffuse, vUv);
vec2 uv = (vUv - 0.5) * 2.0;
float vignette = 1.0 - dot(uv, uv) * uStrength;
vignette = clamp(vignette, 0.0, 1.0);
gl_FragColor = vec4(colour.rgb * vignette, colour.a);
}
` ,
};
const vignettePass = new ShaderPass (vignetteShader);
vignettePass.uniforms ['uStrength' ].value = 0.7 ;
composer.addPass (vignettePass);
Selective Bloom (Objects Only) Bloom only selected objects without affecting the full scene.
const BLOOM_LAYER = 1 ;
const bloomLayer = new THREE .Layers ();
bloomLayer.set (BLOOM_LAYER );
emissiveMesh.layers .enable (BLOOM_LAYER );
const darkMaterial = new THREE .MeshBasicMaterial ({ color : 0x000000 });
const materialMap = new Map ();
function darkenNonBloomed (obj ) {
if (obj.isMesh && !bloomLayer.test (obj.layers )) {
materialMap.set (obj.uuid , obj.material );
obj.material = darkMaterial;
}
}
function restoreMaterials (obj ) {
if (materialMap.has (obj.uuid )) {
obj.material = materialMap.get (obj.uuid );
materialMap.delete (obj.uuid );
}
}
function render ( ) {
scene.traverse (darkenNonBloomed);
bloomComposer.render ();
scene.traverse (restoreMaterials);
finalComposer.render ();
}
Colour Grading — LUT Pass Apply a 3D look-up table for colour grading.
import { LUTPass } from 'three/addons/postprocessing/LUTPass.js' ;
import { LUTCubeLoader } from 'three/addons/loaders/LUTCubeLoader.js' ;
new LUTCubeLoader ().load ('lut/warm.cube' , result => {
const lutPass = new LUTPass ();
lutPass.lut = result.texture3D ;
lutPass.intensity = 1.0 ;
composer.addPass (lutPass);
});
Resize Handling function onWindowResize ( ) {
const w = window .innerWidth ;
const h = window .innerHeight ;
camera.aspect = w / h;
camera.updateProjectionMatrix ();
renderer.setSize (w, h);
composer.setSize (w, h);
if (fxaaPass) {
fxaaPass.material .uniforms ['resolution' ].value .set (
1 / (w * renderer.getPixelRatio ()),
1 / (h * renderer.getPixelRatio ()),
);
}
}
window .addEventListener ('resize' , onWindowResize);
Performance Tips
Fewer passes = better — each pass is a full-screen render; keep total passes under 5
HalfFloatType render target — required for HDR bloom; higher precision than UnsignedByteType
FXAA over MSAA for post-processing pipelines — MSAA doesn't apply after render-to-target
Disable passes when not visible — pass.enabled = false skips execution entirely
Reduce resolution for expensive passes — halve the render target size for SSAO/DoF
Profile with Spector.js — inspect each pass's GPU cost individually
if (isMobile) {
bloomPass.enabled = false ;
}
const halfResTarget = new THREE .WebGLRenderTarget (
window .innerWidth / 2 ,
window .innerHeight / 2 ,
);
See Also
threejs-shaders — writing custom fragment shaders for ShaderPass
threejs-fundamentals — renderer setup and pixel ratio
threejs-materials — MeshPhysicalMaterial transmission as alternative to DoF
three-js-best-practices — GPU budget and mobile scaling rules