Guides
Waterfalls
A waterfall joins an upper body of water to a lower one. You give it a lip, a landing point and a width. It builds the falling sheet, the spray and mist, the plunge-pool churn, and a clip that stops the upstream water exactly at the lip.
y = 3 onto the main run. Spray droplets and mist are soft particles against the scene depth, and the churn and foam plume come from the plunge in the river shader.#Add one
water.addWaterfall({
top: new THREE.Vector3(0, 3, -11), // centre of the lip; y = the upstream water level
bottom: new THREE.Vector3(0, 0, -9.8), // where the curtain meets the pool; y = the pool level
width: 5,
flow: 1, // streak speed, spray power, plunge foam
});The horizontal distance from top to bottom is the throw, and the fall direction is bottom − top in xz. For a drop that is almost vertical, where top and bottom share an x and z, pass direction as a Vector2 to say which way the water falls.
#What gets built
| Part | What you see |
|---|---|
| Sheet | A ballistic curtain in time of flight from the lip. It starts as glassy, refracting water and becomes an aerated curtain whose streaks speed up as they fall. It widens by 12 % on the way down |
| Veil | A second, slightly wider layer pushed out from the sheet, with ragged edges |
| Spray | Additive droplets thrown from the plunge, spray: true by default |
| Mist | Billowing puffs above the pool, mist: true by default |
| Plunge | Dense boiling foam, a foam plume carried downstream, and ripple rings in the pool (drawn by the river or lake surface below) |
| Lip clip | With clipUpstream: true, water of any body at top.y beyond the lip line is discarded, so the upper river never overhangs the edge |
| Splash zone | Materials passed to patchMaterial() get wet in a zone around the plunge |
Particle counts come from the quality tier: from 180 spray droplets and 10 mist puffs on low to 1100 and 36 on ultra.
#Line up the bodies
A waterfall doesn't create water above or below it. Put a river or lake at each end.
const lip = new THREE.Vector3(0, 3, -11);
const pool = new THREE.Vector3(0, 0, -9.8);
// upstream: stop the outlet exactly at the lip
water.addRiver({ path: [new THREE.Vector3(0, 3, -17), lip], width: 6, extend: [0, 0] });
water.addWaterfall({ top: lip, bottom: pool, width: 5 });
// downstream: start the main river at the landing point
water.addRiver({ path: [pool, new THREE.Vector3(3, 0, 4), new THREE.Vector3(-2, 0, 20)], width: 7 });- Use
extend: [0, 0]on the upstream river. The lip clip hides any overshoot, but a river that stops short leaves a gap. - Start the downstream body at
bottomor slightly upstream of it, so the plunge churn lands on water. - Make the waterfall's
widthabout the width of the river feeding it. The demo uses 1.7 × the outlet's half width.
#The plunge pool
carveTerrain() digs a bowl at the landing point:
| Option | Default | |
|---|---|---|
plungeDepth | min(2.2, 0.6 + 0.3 × drop) | Depth below the pool level |
plungeRadius | 0.55 × width | Bowl radius. It also sets the size of the churn and the foam plume |
A 3 m drop gives a 1.5 m deep pool. The foam strength grows with flow and with the drop, up to 2 m.
#Limits
- At most 4 waterfalls feed lip clips, plunge foam, ripple rings and splash zones. You can add more, but the fifth one and after only draw their sheet and particles.
- The sheet is a fixed 28 × 36 grid laid out on a parabolic, ballistic profile. It is shaded to look like falling water, not simulated.
flowscales the look, not the physics. There is no mass flow linking a waterfall to the rivers around it.