A multi-material sandbox with three streams that mix in mid-air.
Part 4 of Smooth Particle Hydrodynamics
Everything from the previous articles comes together here. Water, sand, and jelly all run in one simulation, side by side. Each particle carries a material tag, and the shader looks up its own stiffness, viscosity, and rest density before computing forces. Jelly particles hold onto each other through springs; sand sticks to itself through high viscosity and static friction; water just flows.
Three emitters are already running. Your job is to get in the way. Drop obstacles, paint air blowers that push particles up or sideways, and watch the streams tangle. On WebGPU the scene holds up to 5,000 particles. On machines without WebGPU it falls back to CPU and caps at 500.
The physics for all three materials runs in a single compute shader. Each particle reads its material index, looks up the right stiffness and viscosity from a small uniform array, and computes its own forces. The neighbor loop does not care which material a particle is; it treats them uniformly through the same SPH kernel. Mixtures fall out for free.
Springs for jelly run in their own compute pass before forces. Each jelly particle stores up to four neighbor indices that were within range at spawn time, and the spring pass applies a stiff restoring force toward each one's rest length. The fixed buffer keeps it simple and fast: sentinel values mark empty slots, and that's it.
Everything stays on a single thread of JavaScript above the GPU, mostly to handle the user tools and particle spawning. The compute shader does the real work. If your browser does not support WebGPU the same physics still runs on CPU, just at a lower particle budget. The same ideas from Part 2 and Part 3 scaled out and combined in one place.