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 コミュニティが作成したAIスキルを発見・探索
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
直接コマンドでは確認用 Prompt が省略されます。実行前にソースを確認してください。
npx skills add https://github.com/afovea/game-dev-skills --skill threejs-postprocessingコマンドは1行のまま表示されます。コピー前に横へスクロールして全体を確認してください。
ローカルで確認しますか?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