Emergent behavior from local rules
Boids (flocking) Every boid follows three rules and only looks at neighbors inside its view radius: separation (do not crowd your neighbors), alignment (steer like your neighbors) and cohesion (move toward the center of your neighbors). No boid knows the flock. Still, flocks form, split and merge. Moving the mouse adds a predator the boids flee from. Wikipedia
Particle Life Particles have a type, shown by color. A random matrix says how strongly type A is attracted to or repelled by type B. Very close particles always repel each other, so they do not collapse into one point. From these simple pair forces, cells, chains and orbiting groups appear. Re-roll the matrix to get a new world. particle-life.com
GPU Parallelization Each agent needs the state of all other agents. If the agents were updated in place, some would read new and some old values. So every frame has two passes: first the current state is copied, then one GPU thread per agent reads the copy and writes the new state. 64 threads form one workgroup. Wikipedia
Original work
- Craig W. Reynolds (1987): Flocks, Herds, and Schools: A Distributed Behavioral Model
- Jeffrey Ventrella (2017): Clusters (Particle Life)
How it works
How the simulation runs, step by step:
- Data layout: positions are stored as vec4 [x, y, type, 0] and velocities as vec4 [vx, vy, 0, 0], 16 bytes per agent, so the GPU reads aligned blocks.
- Each frame runs two compute dispatches: copy (current to previous) and step (read previous, write current). The renderer always reads the current buffer.
- The step kernel runs one thread per agent, 64 threads per workgroup. Each thread loops over all agents, so the work grows with N².
- The world wraps around at the edges (torus). Neighbor distances use the shortest way around, so flocks can cross the border.
- Without WebGPU the same math runs on the CPU in JavaScript, capped at 1200 agents. The GPU path allows up to 8192.
Source code:boids.shader.tsboids-gpu.strategy.tsboids-cpu-physics.ts
Note Simplifications in this demo:
- Every agent checks every other agent (O(N²)). There is no spatial grid. This is why the GPU is limited to 8192 agents and the CPU path to 1200.
- The world is a torus: agents that leave one edge enter on the opposite edge, and distances are measured the short way around.
- The force constants are tuned by eye, not by physics. Friction is applied per frame, so the look depends slightly on the frame rate.
Move the mouse over the canvas: the boids flee from it. The color shows the flight direction.
