The Coral Reef — A First-Person Dive with 500 Boids-Powered Fish
Walk along the bottom of a coral reef. Schools of 500 fish part as you swim past. Caustic light dances on the sand. Kelp sways. The whole reef is procedural and inhabited within a second.
What this is
A first-person dive at the bottom of a procedurally-generated coral reef. 500 fish in 6 distinct schools roam the scene under real Boids rules with cross-school separation. 140 coral clusters, 320 swaying kelp ribbons, animated Voronoi caustics on the sand floor, sun shafts piercing the surface, bubbles trailing behind the camera. Volumetric blue-green fog deepens with depth. The reef should feel populated within one second of load.
Why this is mind-blowing
Most "underwater" demos are static. This one is alive — fish swim with purpose, react to your presence, school cohesively, and fan apart when you invade. The whole ecology is procedural, GPU-instanced, and obeys 50-year-old flocking rules in real time. One paragraph of prompt, full reef.
Build a first-person 3D coral reef environment in Three.js. Procedural
seafloor with caustic light from above via a fragment-shader Voronoi
animation. 500-fish schools running a real Boids algorithm
(separation/alignment/cohesion) on the CPU, rendered via InstancedMesh.
Procedural coral and kelp using marching-cubes meshes with subtle vertex
displacement for wave motion. WASD swims, mouse looks. Fog thickens with
depth. Bubble particles trail behind you. The entire reef should feel
inhabited within 1 second of load.
Paste this into Claude, Cursor, or Copilot. Change one thing that matters to you.
What I learned shipping it
- A 3D spatial hash (6m grid cells) keeps Boids at O(N) instead of O(N²). 500 fish at 30Hz with full separation/alignment/cohesion runs comfortably alongside the GL render loop.
- Adding the camera as a 'predator' avoidance term in the Boids step is the move that sells immersion. Schools visibly part as you swim into them — without that, fish look painted on.
- Caustic light is just animated Voronoi noise in a fragment shader. The model knows the recipe — you just say 'caustics.'