Install
Terminal · npx$
npx skills add https://github.com/cloudai-x/threejs-skills --skill threejs-postprocessingWorks with Paperclip
How Threejs Postprocessing fits into a Paperclip company.
Threejs Postprocessing drops into any Paperclip agent that handles this kind of work. Assign it to a specialist inside a pre-configured PaperclipOrg company and the skill becomes available on every heartbeat — no prompt engineering, no tool wiring.
S
SaaS FactoryPaired
Pre-configured AI company — 18 agents, 18 skills, one-time purchase.
$27$59
Explore packSource file
SKILL.md602 linesExpandCollapse
---name: threejs-postprocessingdescription: 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 ```javascriptimport * 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, // strength 0.4, // radius 0.85, // threshold);composer.addPass(bloomPass); // Animation loop - use composer instead of rendererfunction animate() { requestAnimationFrame(animate); composer.render(); // NOT renderer.render()}``` ## EffectComposer Setup ```javascriptimport { 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) ```javascriptimport { UnrealBloomPass } from "three/addons/postprocessing/UnrealBloomPass.js"; const bloomPass = new UnrealBloomPass( new THREE.Vector2(window.innerWidth, window.innerHeight), 1.5, // strength - intensity of glow 0.4, // radius - spread of glow 0.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. ```javascriptimport { 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 pass scene.traverse(darkenNonBloomed); composer.render(); scene.traverse(restoreMaterial); // Render final scene over bloom renderer.render(scene, camera);}``` ### FXAA (Anti-Aliasing) ```javascriptimport { 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) ```javascriptimport { 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) ```javascriptimport { 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) ```javascriptimport { BokehPass } from "three/addons/postprocessing/BokehPass.js"; const bokehPass = new BokehPass(scene, camera, { focus: 10.0, // Focus distance aperture: 0.025, // Aperture (smaller = more DOF) maxblur: 0.01, // Max blur amount}); composer.addPass(bokehPass); // Update focus dynamicallybokehPass.uniforms["focus"].value = distanceToTarget;``` ### Film Grain ```javascriptimport { FilmPass } from "three/addons/postprocessing/FilmPass.js"; const filmPass = new FilmPass( 0.35, // noise intensity 0.5, // scanline intensity 648, // scanline count false, // grayscale); composer.addPass(filmPass);``` ### Vignette ```javascriptimport { 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 intensity composer.addPass(vignettePass);``` ### Color Correction ```javascriptimport { 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); // Multiply composer.addPass(colorPass);``` ### Gamma Correction ```javascriptimport { GammaCorrectionShader } from "three/addons/shaders/GammaCorrectionShader.js"; const gammaPass = new ShaderPass(GammaCorrectionShader);composer.addPass(gammaPass);``` ### Pixelation ```javascriptimport { RenderPixelatedPass } from "three/addons/postprocessing/RenderPixelatedPass.js"; const pixelPass = new RenderPixelatedPass(6, scene, camera); // 6 = pixel size composer.addPass(pixelPass);``` ### Glitch Effect ```javascriptimport { GlitchPass } from "three/addons/postprocessing/GlitchPass.js"; const glitchPass = new GlitchPass();glitchPass.goWild = false; // Continuous glitching composer.addPass(glitchPass);``` ### Halftone ```javascriptimport { HalftonePass } from "three/addons/postprocessing/HalftonePass.js"; const halftonePass = new HalftonePass(window.innerWidth, window.innerHeight, { shape: 1, // 1 = dot, 2 = ellipse, 3 = line, 4 = square radius: 4, // Dot size rotateR: 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 ```javascriptimport { 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. ```javascriptimport { ShaderPass } from "three/addons/postprocessing/ShaderPass.js"; const CustomShader = { uniforms: { tDiffuse: { value: null }, // Required: input texture time: { 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 distortion uv.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 ```javascriptconst 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 ```javascriptconst 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 ```javascriptimport { 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 clearing renderer.autoClear = false; renderer.clear(); bgComposer.render(); // Render foreground over it renderer.clearDepth(); fgComposer.render();}``` ## WebGPU Post-Processing (Three.js r150+) ```javascriptimport { 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 1. **Limit passes**: Each pass adds a full-screen render2. **Lower resolution**: Use smaller render targets for blur passes3. **Disable unused effects**: Toggle passes on/off4. **Use FXAA over MSAA**: Less expensive anti-aliasing5. **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 ```javascriptfunction 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 resolutions if (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 development- `threejs-textures` - Render targets- `threejs-fundamentals` - Renderer setupRelated skills
Threejs Animation
Handles the full Three.js animation pipeline from basic procedural motion to complex skeletal rigs with blend trees. Covers AnimationMixer setup, keyframe track
Threejs Fundamentals
Install Threejs Fundamentals skill for Claude Code from cloudai-x/threejs-skills.
Threejs Geometry
Install Threejs Geometry skill for Claude Code from cloudai-x/threejs-skills.