Interactive terrain erosion in the browser — WebGPU compute (with a WebGL2 fallback), simulating drainage networks, valley carving, sediment deposition and debris flow over geological time in seconds.
A 4096² range eroding to maturity (1600 iterations, ~5 min of compute),
rendered with the capture → replay pipeline: state snapshots are saved
during the run, then re-rendered with any style/camera — here the paper
palette with an orbiting camera and a change-paced, interpolated
timeline. Full-quality mp4. Reproduce with
scripts/capture-frames.mjs + scripts/render-frames.mjs.
Open the app, and it seeds a 1024² mountain range and erodes it to
maturity in one hands-off turbo run (~15 s on an M-class GPU, progress
shown live) — dendritic river networks, carved ridge-valley texture,
sediment basins — then pauses for you to explore, tune, and export.
(Skip the bootstrap with ?boot=off.)
npm install
npm run dev # http://localhost:5183 (Chrome/Edge for WebGPU)Everything runs hands-off on load. Useful controls:
- seed / grid (world folder): every seed is a new range, up to 4096² on WebGPU. Physics stays resolution-independent: above 1024² the soil model scales particle count ∝ area and particle path length ∝ grid, so maturity holds at ~1600 turbo iterations (≈2 min at 2048², ≈10 min at 4096² on an M2 Max). Below 1024² the auto-pause scales instead (400 @ 512²).
- run turbo: batched iterations at full speed (thousands/second).
- run multiscale: coarse-to-fine schedule, e.g.
512:12000,1024:4000. - style:
relief(grayscale hillshade + drainage threads),paper(warm hypsometric ramp + translucent discharge belts, after the paper's figures) ornatural(hypsometric palette with water surfaces). - export: PNG-16 / float TIFF / EXR heightmaps, GLB/OBJ meshes, and full simulation checkpoints.
soillib (classic, default) — a faithful TypeScript + WGSL port of the particle erosion model from soillib by Nicholas McDonald: hydraulic particles with tracked discharge/momentum fields, equilibrium sediment transfer, and bank-stability debris flow. This is a transient model (no uplift): it carves an initial fBm range and the app auto-pauses at scenic maturity. WebGPU only (needs read-write atomics). Includes a visit-safe stability fix for the debris kernel's concurrent-particle overshoot at high resolution.
geotransport (paper) — an independent implementation of the
stochastic geomorphological transport method of McDonald & Cordonnier
(2026): a generic Monte-Carlo solver for div(φ·v) = S − R·φ drives
water, sediment, debris and momentum transport, with fluvial/landslide/
debris-flow erosion updating the height field under tectonic uplift.
Three cross-validated backends:
| backend | role | notes |
|---|---|---|
| CPU (f64) | reference | pure TS, runs in vitest |
| WebGL2 | fallback | splat-based accumulation (no atomics in WebGL) |
| WebGPU | default | 64-bit fixed-point atomics — order-independent, bit-deterministic per seed; 27–70× faster than the WebGL path |
The braided plain (exp) preset targets the paper's braided-river regime
(piedmont range shedding sediment onto a tilted basin). Run turbo to
~8k iterations at 512² and connected anastomosing channel networks span
the plain. Three ingredients were needed to break the sheet-flow speckle
deadlock (at sub-millimetre depths the 1/h friction term amplifies
Monte-Carlo noise into a channel-fragmenting feedback): an alluvial
friction floor applied to the plain only (frictionHMinM, band-masked so
the range keeps bedrock thin-flow and still carves), partial orographic
rain (rainMountainFrac — range-fed channels out-compete local rills),
and heavy temporal filtering (β = 0.03). Longer runs over-aggrade and
regress. Remaining gap to the paper's figures: wide multi-thread braid
belts need lateral channel wandering that this configuration does not
yet reproduce.
npm test # CPU suites: solver convergence, invariants, goldens
npm run validate # headless Chrome: cone test (§15.1), single-step
# parity, trajectory gates — CPU vs WebGL vs WebGPU
npm run bench:headlessBaseline numbers and methodology live in docs/PERF.md (Apple M2 Max: 1.1 / 3.0 / 14.1 ms per full iteration at 256² / 512² / 1024² on WebGPU).
- Nicholas McDonald and Guillaume Cordonnier. Stochastic Geomorphological Transport for Terrain Erosion Simulation. ACM Transactions on Graphics 45(4), Article 78, 2026.
- Nicholas McDonald, soillib — https://github.com/erosiv/soillib
(LGPL-3.0). soillib's source is not vendored here; the classic model
is a port, and the ported files carry LGPL-3.0 SPDX headers:
src/sim/soil/SoilCpu.ts,src/gpu/wgsl/soil.wgsl,src/gpu/wgsl/soilFilter.wgsl.
MIT (LICENSE), with one exception: the three files ported from soillib (listed above) are derivative works and remain LGPL-3.0 (LICENSE.LGPL-3.0) — each carries an SPDX header.

