Renderer · interface

WaterBody

A body of water: the sea, a fountain's basin, a tank, a puddle.

Explained in Hello world.

interface WaterBody
import type { WaterBody } from '@driftengine/core';

In depth

One description and one material for all of them. The sea is not a special case with a shader of its own — it is this, unbounded and dense, and a fountain is this, bounded and clear. The first attempt gave a basin its own faked surface, and the correction was the right one: water should be a single configurable concept — density, visibility, up to fully transparent — rather than a trick per body of water. The sea is water too, and it gets the same reusable component with the same abilities.

So every body gets the waves, the Fresnel, the specular, the fog and the planar reflection, and differs only in these numbers.

Properties

NameTypeDescription
levelnumberResting height of the surface.
deepColorVec3
shallowColorVec3
densityoptionalnumberHow much of what lies beneath it the water hides, looked straight down, 0 to 1. A sea hides its own floor; a fountain shows the tiles at the bottom of it; zero is glass. Only this end is configurable — at a grazing angle every water surface goes reflective, which is Fresnel rather than a property of the liquid.
visibilityoptionalnumberThe surface's overall visibility, 0 to 1. Zero draws nothing.
mirroroptionalnumberHow much it mirrors regardless of viewing angle, 0 to 1.
More

Zero is physics — reflection by Fresnel alone, which is what an ocean does and what leaves a basin looking blank from directly above, since at that angle the Fresnel term is a few percent. A pool is looked into, so it is allowed to cheat; the sea is not, and keeps zero.

waveScaleoptionalnumberHow built-up its waves are, as a multiple of what the wind is doing.
More

One is the open sea. A basin wants a fraction of it: the same wave field at a scale where it reads as a surface breathing rather than as a swell rolling through somebody's fountain.

agitationoptionalnumberHow worked-up this body is on its own, 0 to 1, ignoring the wind entirely.
More

For water the weather cannot reach: a cistern, a flooded corridor, a tank. Zero is as near still as this surface goes — never glass, because dead-flat water reads as a mirror rather than as calm — and one matches a fully developed sea.

Omitted, the body takes its state from the wind it is drawn with, which is what an ocean, a lake or a fountain in a courtyard should do.

boundsoptionalWaterBoundsA bounded body: where it is, how far it reaches along each of its own axes, and which way those axes point.
More

Omitted, the body is the endless ocean — the camera-following sheet the sea has always been. Given, it is a fixed rectangle of water sitting exactly where it was put.

It was a centre and one half-extent until 2026-08-28, and a square cannot bound a channel. Reported from outside: a 3 by 21 metre ditch bounded by the square that contains it floods eighteen metres of field either side, so the workaround was a single unbounded body at the ditches' water level with the world's whole ground raised above it — a technically flooded world, held up by a rule nobody can see, that nothing anywhere may be drawn below the water line. It cost that consumer one bug already: a distant ground plane 1.6 m down, correct for its own reasons, put the village in a lake.

What this cannot do is bend. A canal that turns is one body per straight run, and where two runs meet at a corner their sheets overlap and the blend doubles there. That is cheap to place and honest about what it draws; what would change it is a consumer measuring that seam as the problem, which is the day bounds grows a polyline and a width.