Pass Effects
What This Example Shows
This example demonstrates the Pass Effect system for full-screen post-processing. Switch between 5 presets to see different effect chains applied to a sprite scene:
| Preset | Passes | Description |
|---|---|---|
| Clean | 0 | No post-processing |
| CRT Arcade | 1 | Full CRT composite — curvature, scanlines, bloom, vignette, and color bleed |
| Handheld | 4 | Posterize + LCD grid + backlight bleed + vignette |
| VHS Tape | 3 | VHS distortion + static noise + chromatic aberration |
| Retro PC | 3 | Color quantize + scanlines + vignette |
Defining Pass Effects
Use createPassEffect with a schema for parameters and a TSL node builder:
import { createPassEffect } from 'three-flatland'import { crtComplete } from '@three-flatland/nodes'import { convertToTexture } from 'three/tsl'
const CRTPass = createPassEffect({ name: 'crt', schema: { curvature: 0.08, scanlineIntensity: 0.18, vignetteIntensity: 0.3, bloomIntensity: 0.15, colorBleed: 0.0012, }, pass: ({ uniforms }) => (input, uv) => { const tex = convertToTexture(input) return crtComplete(tex, uv, { curvature: uniforms.curvature, scanlineIntensity: uniforms.scanlineIntensity, vignetteIntensity: uniforms.vignetteIntensity, bloomIntensity: uniforms.bloomIntensity, colorBleed: uniforms.colorBleed, }) },})import { createPassEffect } from 'three-flatland/react'import { crtComplete } from '@three-flatland/nodes'import { convertToTexture } from 'three/tsl'
const CRTPass = createPassEffect({ name: 'crt', schema: { curvature: 0.08, scanlineIntensity: 0.18, vignetteIntensity: 0.3, bloomIntensity: 0.15, colorBleed: 0.0012, }, pass: ({ uniforms }) => (input, uv) => { const tex = convertToTexture(input) return crtComplete(tex, uv, { curvature: uniforms.curvature, scanlineIntensity: uniforms.scanlineIntensity, vignetteIntensity: uniforms.vignetteIntensity, bloomIntensity: uniforms.bloomIntensity, colorBleed: uniforms.colorBleed, }) },})Adding Passes at Runtime
Instantiate a pass and add it to Flatland. Passes chain in order — each receives the previous output:
const crt = new CRTPass()flatland.addPass(crt)
// Animate parameters in the render loopcrt.curvature = 0.12
// Swap presets by clearing and adding new passesflatland.clearPasses()flatland.addPass(new PosterizePass()).addPass(new VignettePass())import { useEffect, useRef } from 'react'import { useFrame } from '@react-three/fiber/webgpu'
function FlatlandScene({ preset }) { const flatlandRef = useRef(null)
useEffect(() => { const flatland = flatlandRef.current flatland.clearPasses() const active = createPreset(preset) for (const p of active.passes) flatland.addPass(p) }, [preset])
useFrame((_, delta) => { flatlandRef.current?.render(gl) })
return ( <flatland ref={flatlandRef} viewSize={80} clearColor={0x1a1a2e}> {/* sprites */} </flatland> )}Next Steps
- Pass Effects Guide — Full API reference and pass chain architecture
- TSL Nodes — Per-sprite material effects