Skip to content

Repository files navigation

Fish Boid Simulation

A browser-based 3D flocking (boids) simulation of fish, built with React Three Fiber. Twenty fish swim inside a bounded tank, each running the same small set of steering rules against its own local neighborhood — separation, alignment, cohesion, wander, field-of-view culling, and Fibonacci-spiral obstacle evasion — with no central script driving the group. The school behavior emerges from the math.

What's inside

  • CPU-based O(N²) boid simulation — position/velocity state lives in plain Float32Arrays outside React, updated once per frame in a single loop
  • Seven-rule steering system — separation, alignment, cohesion, wander, FOV-based neighbor culling, Fibonacci-cone obstacle evasion with panic-weighted blending, and hard boundary clamping
  • Rapier physics integration — static wall colliders used purely for raycasting (obstacle detection), not for moving the fish themselves
  • Custom GLSL vertex shader — swims the fish model via per-vertex sine displacement instead of skeletal animation, for performance at scale
  • Underwater atmosphere — exponential fog, animated caustics floor shader, directional lighting with shadows
  • Glass-morphism intro overlay — a draggable "hatch" panel with a porthole preview of a single fish (poke it to spin it), listing the seven boid rules

Dependencies

Beyond the base Vite + React setup, this project uses:

Package Why
three Core 3D engine — peer dependency of R3F
@react-three/fiber React renderer for three.js — lets the scene be written as JSX
@react-three/drei Helper components (OrbitControls, etc.)
leva Live-tunable debug panel for boid parameters (weights, speeds, radii)
@react-three/rapier R3F bindings for the Rapier physics engine — used here for raycasting-based obstacle detection, not gravity/collision response
framer-motion Drag gesture + spring animation for the intro overlay's "slide to dive in" interaction

Setup

npm install

This pulls in everything listed in package.json, including the above.

Running it

npm run dev

Then open the local URL Vite prints (typically http://localhost:5173).

Controls

  • Intro screen: drag the panel right (or drag past roughly a third of the screen width) to dismiss it and reveal the tank. Hover/poke the fish in the porthole to spin it.
  • Main scene: click-drag to orbit, scroll to zoom (bounded so you can't zoom outside the tank walls).
  • Leva panel (top-right): live-tune boid behavior — perception radius, steering weights, wander intensity, FOV angle, obstacle vision radius, and panic curve exponent.

Known limitations / next steps

  • Simulation is O(N²) CPU-bound — fine at ~20 fish, would need spatial partitioning or a GPU compute (GPGPU) rewrite to scale to hundreds/thousands
  • The custom fish swim shader and caustics floor shader are hand-written ShaderMaterials, so they don't automatically receive scene lighting or shadows the way MeshStandardMaterial does — this is a known trade-off, not a bug
  • Wall

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages