--- name: r3f-postprocessing description: React Three Fiber post-processing - @react-three/postprocessing, bloom, DOF, screen effects. Use when adding visual effects, color grading, blur, glow, or creating custom screen-space shaders. --- # React Three Fiber Post-Processing ## Quick Start ```tsx import { Canvas } from '@react-three/fiber' import { EffectComposer, Bloom, Vignette } from '@react-three/postprocessing' function Scene() { return ( ) } ``` ## Installation ```bash npm install @react-three/postprocessing postprocessing ``` ## EffectComposer The container for all post-processing effects. ```tsx import { EffectComposer } from '@react-three/postprocessing' function Scene() { return ( {/* Scene content */} ... {/* Post-processing - must be inside Canvas, after scene content */} {/* Effects go here */} ) } ``` ## Common Effects ### Bloom (Glow) ```tsx import { EffectComposer, Bloom } from '@react-three/postprocessing' import { BlendFunction } from 'postprocessing' // For objects to glow, use emissive materials 1 /> ``` ### Selective Bloom ```tsx import { EffectComposer, Bloom, Selection, Select } from '@react-three/postprocessing' function Scene() { return ( {/* This mesh will bloom */} {/* This mesh will NOT bloom */} ) } ``` ### Depth of Field ```tsx import { EffectComposer, DepthOfField } from '@react-three/postprocessing' // With target object import { useRef } from 'react' function Scene() { const targetRef = useRef() return ( <> ) } ``` ### Vignette ```tsx import { EffectComposer, Vignette } from '@react-three/postprocessing' ``` ### Noise ```tsx import { EffectComposer, Noise } from '@react-three/postprocessing' import { BlendFunction } from 'postprocessing' ``` ### Chromatic Aberration ```tsx import { EffectComposer, ChromaticAberration } from '@react-three/postprocessing' import { BlendFunction } from 'postprocessing' ``` ### SSAO (Screen Space Ambient Occlusion) ```tsx import { EffectComposer, SSAO } from '@react-three/postprocessing' import { BlendFunction } from 'postprocessing' ``` ### Outline ```tsx import { EffectComposer, Outline, Selection, Select } from '@react-three/postprocessing' function Scene() { return ( {/* Outlined object */} {/* Non-outlined object */} ) } ``` ### Color Grading ```tsx import { EffectComposer, BrightnessContrast, HueSaturation } from '@react-three/postprocessing' ``` ### Tone Mapping ```tsx import { EffectComposer, ToneMapping } from '@react-three/postprocessing' import { ToneMappingMode } from 'postprocessing' ``` ### Glitch ```tsx import { EffectComposer, Glitch } from '@react-three/postprocessing' import { GlitchMode } from 'postprocessing' ``` ### Pixelation ```tsx import { EffectComposer, Pixelation } from '@react-three/postprocessing' ``` ### Scanline ```tsx import { EffectComposer, Scanline } from '@react-three/postprocessing' import { BlendFunction } from 'postprocessing' ``` ### Grid ```tsx import { EffectComposer, Grid } from '@react-three/postprocessing' import { BlendFunction } from 'postprocessing' ``` ### DotScreen ```tsx import { EffectComposer, DotScreen } from '@react-three/postprocessing' import { BlendFunction } from 'postprocessing' ``` ### SMAA (Anti-Aliasing) ```tsx import { EffectComposer, SMAA } from '@react-three/postprocessing' {/* Disable MSAA when using SMAA */} ``` ### FXAA (Anti-Aliasing) ```tsx import { EffectComposer, FXAA } from '@react-three/postprocessing' ``` ## Combining Multiple Effects ```tsx import { EffectComposer, Bloom, Vignette, ChromaticAberration, Noise, SMAA } from '@react-three/postprocessing' import { BlendFunction } from 'postprocessing' function PostProcessing() { return ( {/* Glow effect */} {/* Color aberration */} {/* Film grain */} {/* Vignette */} {/* Anti-aliasing (should be last) */} ) } ``` ## Custom Effects ### Using postprocessing Effect Class ```tsx import { forwardRef, useMemo } from 'react' import { Effect, BlendFunction } from 'postprocessing' import { Uniform } from 'three' // Fragment shader const fragmentShader = ` uniform float time; uniform float intensity; void mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) { vec2 distortedUv = uv; distortedUv.x += sin(uv.y * 10.0 + time) * 0.01 * intensity; vec4 color = texture2D(inputBuffer, distortedUv); outputColor = color; } ` // Effect class class WaveDistortionEffect extends Effect { constructor({ intensity = 1.0, blendFunction = BlendFunction.NORMAL } = {}) { super('WaveDistortionEffect', fragmentShader, { blendFunction, uniforms: new Map([ ['time', new Uniform(0)], ['intensity', new Uniform(intensity)], ]), }) } update(renderer, inputBuffer, deltaTime) { this.uniforms.get('time').value += deltaTime } } // React component wrapper export const WaveDistortion = forwardRef(({ intensity = 1.0, blendFunction }, ref) => { const effect = useMemo(() => new WaveDistortionEffect({ intensity, blendFunction }), [intensity, blendFunction]) return }) // Usage ``` ### Shader with wrapEffect ```tsx import { wrapEffect } from '@react-three/postprocessing' import { Effect, BlendFunction } from 'postprocessing' import { Uniform } from 'three' class InvertEffect extends Effect { constructor({ blendFunction = BlendFunction.NORMAL } = {}) { super('InvertEffect', ` void mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) { outputColor = vec4(1.0 - inputColor.rgb, inputColor.a); } `, { blendFunction, }) } } export const Invert = wrapEffect(InvertEffect) // Usage ``` ## Conditional Effects ```tsx import { useState } from 'react' import { EffectComposer, Bloom, Vignette, Glitch } from '@react-three/postprocessing' function ConditionalPostProcessing() { const [effects, setEffects] = useState({ bloom: true, vignette: true, glitch: false, }) return ( <> {effects.bloom && ( )} {effects.vignette && ( )} {effects.glitch && ( )} {/* UI to toggle effects */}
) } ``` ## Animated Effects ```tsx import { useRef } from 'react' import { useFrame } from '@react-three/fiber' import { EffectComposer, Bloom, ChromaticAberration } from '@react-three/postprocessing' function AnimatedEffects() { const bloomRef = useRef() const chromaticRef = useRef() useFrame(({ clock }) => { const t = clock.elapsedTime // Animate bloom intensity if (bloomRef.current) { bloomRef.current.intensity = 1 + Math.sin(t) * 0.5 } // Animate chromatic aberration if (chromaticRef.current) { const offset = Math.sin(t * 2) * 0.002 chromaticRef.current.offset.set(offset, offset) } }) return ( ) } ``` ## N8AO (High Quality AO) ```tsx import { EffectComposer } from '@react-three/postprocessing' import { N8AO } from '@react-three/postprocessing' ``` ## God Rays ```tsx import { EffectComposer, GodRays } from '@react-three/postprocessing' import { useRef } from 'react' function Scene() { const sunRef = useRef() return ( {/* Sun mesh (light source for god rays) */} {sunRef.current && ( )} ) } ``` ## LUT (Color Lookup Table) ```tsx import { EffectComposer, LUT } from '@react-three/postprocessing' import { LUTCubeLoader } from 'postprocessing' import { useLoader } from '@react-three/fiber' function ColorGradedScene() { const texture = useLoader(LUTCubeLoader, '/luts/cinematic.cube') return ( ) } ``` ## Blend Functions ```tsx import { BlendFunction } from 'postprocessing' // Available blend functions: BlendFunction.SKIP // Skip blending BlendFunction.ADD // Additive BlendFunction.ALPHA // Alpha BlendFunction.AVERAGE // Average BlendFunction.COLOR // Color BlendFunction.COLOR_BURN // Color Burn BlendFunction.COLOR_DODGE // Color Dodge BlendFunction.DARKEN // Darken BlendFunction.DIFFERENCE // Difference BlendFunction.DIVIDE // Divide BlendFunction.DST // Destination BlendFunction.EXCLUSION // Exclusion BlendFunction.HARD_LIGHT // Hard Light BlendFunction.HARD_MIX // Hard Mix BlendFunction.HUE // Hue BlendFunction.INVERT // Invert BlendFunction.INVERT_RGB // Invert RGB BlendFunction.LIGHTEN // Lighten BlendFunction.LINEAR_BURN // Linear Burn BlendFunction.LINEAR_DODGE // Linear Dodge BlendFunction.LINEAR_LIGHT // Linear Light BlendFunction.LUMINOSITY // Luminosity BlendFunction.MULTIPLY // Multiply BlendFunction.NEGATION // Negation BlendFunction.NORMAL // Normal BlendFunction.OVERLAY // Overlay BlendFunction.PIN_LIGHT // Pin Light BlendFunction.REFLECT // Reflect BlendFunction.SATURATION // Saturation BlendFunction.SCREEN // Screen BlendFunction.SET // Set BlendFunction.SOFT_LIGHT // Soft Light BlendFunction.SRC // Source BlendFunction.SUBTRACT // Subtract BlendFunction.VIVID_LIGHT // Vivid Light ``` ## Performance Tips 1. **Limit effect count**: Each effect adds rendering overhead 2. **Use multisampling wisely**: Higher values = slower performance 3. **Disable when not needed**: Toggle `enabled` prop 4. **Lower resolution**: Some effects have resolution props 5. **Profile with DevTools**: Monitor GPU usage ```tsx // Disable all effects ... // Reduce effect quality on mobile const isMobile = /iPhone|iPad|Android/i.test(navigator.userAgent) {!isMobile && } ``` ## See Also - `r3f-shaders` - Custom shader development - `r3f-materials` - Emissive materials for bloom - `r3f-fundamentals` - Canvas and renderer setup