A high-performance WebGPU-based hydraulic erosion simulation that combines multi-directional flow routing, moisture-aware thermal erosion, and a Lattice Boltzmann Method (LBM) for orographic precipitation effects.
Live Demo: https://metarapi.github.io/eulerian-erosion/
- Adaptive FD8 Flow Routing: Utilizes an 8-direction flow model where the distribution exponent adapts to terrain curvature, allowing water to spread realistically on slopes and concentrate in valleys.
- Orographic Precipitation via LBM: A D2Q9 Lattice Boltzmann simulation models airflow over the terrain, generating a density map that biases rainfall. This creates realistic rain shadows on leeward slopes and increased precipitation on windward slopes.
- Dynamic Cloud Layer: A visually rendered cloud layer uses the density map from the LBM simulation to control the size, opacity, and brightness of cloud particles, providing a visual representation of the wind and moisture patterns.
- Dual Water System: Separates water into two types—flowing water for erosion and sediment transport, and still water for pooling in depressions and influencing thermal erosion.
- Shear Stress Erosion Model: Erosion is gated by shear stress, preventing unrealistic erosion from shallow or slow-moving water and concentrating erosive power in deep, fast channels.
- Moisture-Aware Thermal Erosion: The stability of terrain (angle of repose) is dynamically adjusted based on its moisture level, considering surface wetness from flowing water and full immersion in still water.
- Two-Stage Water Redistribution: A novel combination of a continuous, relaxed redistribution during erosion and a final, mass-conserving equilibration step using a Margolus neighborhood binary search.
- Procedural Terrain Generation: Generates initial landscapes using GPU-accelerated, domain-warped fractal Brownian motion (fBm).
- Mountain Chain Synthesis via JFA Blending: Thresholded noise produces seed “ridge nuclei”; a Jump Flood Algorithm builds a distance field whose normalized result is blended with the original noise to create coherent ridge / valley belts.
The simulation is a multi-stage process orchestrated entirely on the GPU.
- Thresholded Domain-Warped fBm (
fBmSimplexNoiseThresholdedForJFA.wgsl)- Produces both a base heightmap (0–1) and seed points where height exceeds
jfaThreshold.
- Produces both a base heightmap (0–1) and seed points where height exceeds
- Jump Flood Algorithm (JFA) (
JFAwithAtomicMax.wgsl)- Propagates nearest-seed information in O(log N) passes.
- A final pass captures the maximum distance for normalization.
- Height / Distance Blending (
blendWithNormalize.wgsl)- Normalizes the distance field and blends it with the original noise based on
blendFactor.
- Normalizes the distance field and blends it with the original noise based on
- Result Copy → becomes the initial terrain fed into erosion.
- Initial Stabilization: Before erosion begins, a D2Q9 Lattice Boltzmann simulation (
LBM.wgsl) is run for a number of steps (lbmInitialSteps) to establish a stable airflow pattern over the terrain, influenced by the globalwindDirection. - Density Map Generation: The LBM simulation outputs a density texture. Low-velocity air pools on the windward side of mountains (high density), while high-velocity air flows over the peaks and into the leeward side (low density).
The simulation runs for a specified number of iterations. Each iteration consists of four main steps:
-
LBM Update (
LBM.wgsl): The wind simulation is advanced by a few steps (lbmStepsPerIter) to react to changes in the terrain from the previous erosion cycle. -
Hydraulic Erosion (
erosionPingPongFD8.wgsl):- Orographic Rainfall: New water droplets are spawned based on a probability derived from the LBM density map. High-density (windward) areas receive more water, while low-density (leeward) areas receive little to none. The
lbmDensityMultipliercontrols the intensity of this effect. - Calculates water flow between cells based on the total water surface height (terrain + water).
- Flow is concentrated or spread based on the terrain's Laplacian (curvature).
- Erosion and deposition occur based on water velocity, slope, and sediment capacity. A shear stress model (
shearShallow,shearDeep) ensures erosion only happens in sufficiently powerful flows.
- Orographic Rainfall: New water droplets are spawned based on a probability derived from the LBM density map. High-density (windward) areas receive more water, while low-density (leeward) areas receive little to none. The
-
Still Water Redistribution (
stillWaterRedistribution.wgsl):- This pass allows still water to settle locally, governed by a relaxation factor (
still_water_relaxation) to ensure stability.
- This pass allows still water to settle locally, governed by a relaxation factor (
-
Thermal Erosion (
thermalErosion.wgsl):- Simulates slope failure due to gravity. The angle of repose is dynamically calculated based on terrain height and moisture (dry, wet, or submerged).
After the main erosion loop, a final set of passes using a Margolus Binary Search (margolusBinaryWaterRedistribution.wgsl) ensures all still water has settled into a physically stable state, forming flat lakes and ponds.
- The final terrain and water data are used to generate a 3D mesh in Babylon.js.
- A dynamic texture is applied to the mesh to color the terrain based on height, slope, and water depth.
- The LBM density map is used to drive a
SolidParticleSystem, rendering a 3D cloud layer that visually corresponds to the moisture patterns.
A detailed tooltip is available for each parameter in the UI.
- General:
Resolution,Iterations - Terrain Generation / Structure:
octaves,zoom,persistence,warpFactor,seed - Mountain Chain Blending:
jfaThreshold: Controls density of ridge seeds.blendFactor: 0 = pure noise; 1 = fully structured ridges.
- Wind & Clouds:
windDirection: Sets the global wind direction for the LBM simulation.lbmDensityMultiplier: Controls the intensity of the orographic rain shadow effect.cloudsEnabled: Toggles the visibility of the 3D cloud layer.cloudGlobalAlpha,cloudAlphaMin,cloudAlphaMax: Control the opacity and appearance of the clouds.
- Hydraulic Erosion:
spawnCycles,spawnDensity,evapRate,depositionRate,flowDepthWeight,shearShallow,shearDeep - Water System:
waterHeightFactor,stillWaterRelaxation - Thermal Erosion:
thermalStrength,maxDeltaPerPass, moisture + elevation talus angles - Final Equilibration:
margolusPasses,margolusBinarySearchIterations
fBmSimplexNoiseThresholdedForJFA.wgsl: Domain-warped fBm + ridge seed thresholding.JFAwithAtomicMax.wgsl: Jump Flood nearest-seed propagation.blendWithNormalize.wgsl: Normalizes distance and blends with noise.LBM.wgsl: D2Q9 Lattice Boltzmann simulation for orographic wind effects.erosionPingPongFD8.wgsl: Hydraulic erosion & sediment transport, driven by LBM density.stillWaterRedistribution.wgsl: Iterative intra-loop settling.thermalErosion.wgsl: Moisture & elevation adaptive talus relaxation.margolusBinaryWaterRedistribution.wgsl: Mass-conserving still water equilibration.
Prerequisites
- Node.js (v18+)
- A modern browser with WebGPU support (e.g., Chrome, Edge).
Quick Start
npm install
npm run devVisit http://localhost:5173 (or the port specified in your terminal).
Build for Production
npm run build
npm run preview@babylonjs/core: 3D rendering enginealpinejs: Reactive UI frameworkflyonui+tailwindcss: UI styling and componentsvite+vite-plugin-glsl: Build system and shader bundling