Post-Processing Effects
Cinematic and stylistic effects using @react-three/postprocessing.
Quick Start npm install @react-three/postprocessing postprocessing
import { Canvas } from '@react-three/fiber'; import { EffectComposer, ChromaticAberration, Vignette, Noise } from '@react-three/postprocessing';
function CinematicScene() { return ( ); }
Core Effects Chromatic Aberration
RGB channel separation for lens distortion or glitch effects.
import { ChromaticAberration } from '@react-three/postprocessing'; import { BlendFunction } from 'postprocessing'; import { Vector2 } from 'three';
// Subtle cinematic fringing
function SubtleChromaticAberration() {
return (
// Intense glitch effect function GlitchChromaticAberration() { const offsetRef = useRef();
useFrame(({ clock }) => { if (offsetRef.current) { const glitch = Math.random() > 0.95 ? 0.01 : 0.002; offsetRef.current.offset.set(glitch, glitch * 0.5); } });
return (
Vignette
Darkened edges for focus and cinematic framing.
import { Vignette } from '@react-three/postprocessing';
// Soft cinematic vignette
function CinematicVignette() {
return (
// Harsh spotlight effect
function SpotlightVignette() {
return
Depth of Field
Simulated camera focus with bokeh blur.
import { DepthOfField } from '@react-three/postprocessing';
// Focus on specific distance
function StaticDOF() {
return (
// Focus follows target object function TrackingDOF({ targetRef }) { const dofRef = useRef(); const { camera } = useThree();
useFrame(() => { if (targetRef.current && dofRef.current) { const distance = camera.position.distanceTo(targetRef.current.position); dofRef.current.target = distance; } });
return
Noise / Film Grain import { Noise } from '@react-three/postprocessing'; import { BlendFunction } from 'postprocessing';
// Subtle film grain
function FilmGrain() {
return
// Heavy VHS noise
function VHSNoise() {
return
Color Grading import { HueSaturation, BrightnessContrast } from '@react-three/postprocessing';
// Desaturated cinematic look
function CinematicGrade() {
return (
<>
// Warm sunset mood
function SunsetGrade() {
return (
<>
// Cold sci-fi atmosphere
function SciFiGrade() {
return (
<>
LUT (Lookup Table) import { LUT } from '@react-three/postprocessing'; import { LookupTexture } from 'postprocessing';
function LUTGrading() { const [lut, setLut] = useState(null);
useEffect(() => { LookupTexture.createLookupTexture('/luts/cinematic.cube').then(setLut); }, []);
if (!lut) return null;
return
Tone Mapping import { ToneMapping } from '@react-three/postprocessing'; import { ToneMappingMode } from 'postprocessing';
function CinematicToneMapping() {
return
Scanlines / CRT Effect import { Scanline } from '@react-three/postprocessing';
function CRTScanlines() {
return
God Rays import { GodRays } from '@react-three/postprocessing';
function VolumetricLight() { const sunRef = useRef();
return (
<>
<EffectComposer>
{sunRef.current && <GodRays sun={sunRef.current} exposure={0.5} decay={0.9} blur />}
</EffectComposer>
</>
); }
Combining Effects
Cinematic Stack
function CinematicStack() {
return (
Retro VHS Stack
function VHSStack() {
return (
Dream Sequence Stack
function DreamStack() {
return (
Animated Effects Time-Driven Color Shift function TimeDrivenEffects() { const hueRef = useRef(); const vignetteRef = useRef();
useFrame(({ clock }) => { const t = clock.elapsedTime; if (hueRef.current) hueRef.current.hue = Math.sin(t * 0.1) * 0.1; if (vignetteRef.current) vignetteRef.current.darkness = 0.4 + Math.sin(t * 2) * 0.1; });
return (
Audio-Reactive Effects function AudioReactiveEffects({ audioData }) { const chromaRef = useRef(); const vignetteRef = useRef();
useFrame(() => { if (!audioData) return; const bass = audioData[0] / 255; const mid = audioData[4] / 255;
if (chromaRef.current) {
const offset = 0.001 + bass * 0.005;
chromaRef.current.offset.set(offset, offset * 0.5);
}
if (vignetteRef.current) {
vignetteRef.current.darkness = 0.3 + mid * 0.3;
}
});
return (
Temporal Collapse Theme
Effects stack for cosmic countdown aesthetic:
function TemporalCollapseEffects() { const chromaRef = useRef();
useFrame(({ clock }) => { if (chromaRef.current) { const pulse = Math.sin(clock.elapsedTime * 1.5) * 0.001; chromaRef.current.offset.set(0.002 + pulse, 0.001 + pulse * 0.5); } });
return (
Performance Tips
Technique Impact Solution
Multiple blur effects High Combine DOF with bloom carefully
High DOF resolution High Use height={480} or lower
LUT loading Medium Preload, cache texture
Many effects Medium Order effects efficiently
function OptimizedEffects() {
return (
Reference See postfx-composer for EffectComposer setup and render targets See postfx-bloom for dedicated bloom techniques See postfx-router for effect selection guidance