Reference
API reference
Everything exported from src/index.js and build/index.js. The types are in build/*.d.ts. Units are metres, seconds and radians unless noted, sea level is y = 0, and colours are linear HDR THREE.Color values.
import {
WaterSystem, BuiltinSky, Buoyancy, Wakes, MAX_HULLS, Caustics,
WaveSpectrum, Bathymetry, FFTWaves, QUALITY_LEVELS,
PRESETS, DEFAULT_PARAMS, getPresetParams,
CAUSTIC_FN_GLSL, SKY_GLSL, NOISE_GLSL,
} from 'naturegl-water';#WaterSystem
WaterSystem.create(options): Promise<WaterSystem>static asyncBuilds the ocean mesh and the built-in sky dome and adds both to options.scene. The constructor is synchronous, since every texture is procedural; create() is async to match the other NatureGL packages, and new WaterSystem(options) works too.
| Option | Type | Default | |
|---|---|---|---|
renderer | THREE.WebGLRenderer | — | Required, WebGL2 |
scene | THREE.Scene | — | Required. The ocean and sky dome are added here |
camera | THREE.PerspectiveCamera | — | Required. The camera render() draws |
quality | 'low', 'medium', 'high', 'ultra' | 'high' | See Quality and performance |
preset | string or Partial<WaterParams> | 'tropical' | Starting params |
bathymetry | BathymetryDesc | — | Seabed for shoaling, breakers and shore foam |
sky | SkyLike | — | External sky. Omit it for the built-in one |
addSky | boolean | true | Add the built-in sky dome to the scene |
manageFog | boolean | true | Keep scene.fog (a FogExp2) matched to the sky haze and fogDensity |
toneMapping | 'aces', 'reinhard', 'none' | 'aces' | Applied by render(). Leave renderer.toneMapping at NoToneMapping |
overlayLayer | number | 30 | Objects on this layer draw after the water |
#Frame
water.update(dt): voidmethodAdvances time by dt seconds (clamped to 0.1). Eases params toward their targets, rebuilds and advances the spectrum, updates the sky, the underwater state, buoyancy, wakes and the foam simulation. Call it once per frame before render(), after you move your objects.
water.render(target?): voidmethodRuns the depth pipeline for scene and camera and composites into target (the canvas by default). Restores renderer.autoClear and the previous render target. See Rendering.
water.renderHDR(): { texture, depthTexture }methodsince 1.1Passes 1–3 only (world, water, overlay) into the pipeline's linear HDR target, with no bloom or tone mapping. depthTexture holds world and water-surface depth. The size is the drawing buffer × renderScale. The underwater colour grade is skipped; the underwater fog is kept.
water.resize(): thismethodRe-reads renderer.getDrawingBufferSize() and resizes the offscreen targets. render() does this on its own; the camera's aspect is yours to update.
water.dispose(): voidmethodRemoves the ocean and sky from the scene and frees the GPU resources.
#Params and presets
water.loadPreset(preset, opts?): thismethodSwitches to a built-in preset by id, or to any partial params object. Missing keys come from DEFAULT_PARAMS. opts.instant skips the ease.
water.setParams(partial, opts?): thismethodChanges some target params; the rest keep their values. opts.instant snaps.
water.getParams(): WaterParamsmethodA deep, JSON-safe copy of the target params. Paste it into a preset file.
| Property | |
|---|---|
params: WaterParams | The targets that presets and setParams write |
current: WaterParams | The eased values in use. Read these for UI sliders |
exposure: number | 1.1 Read-only. What render() tone-maps with |
time: number | Seconds since creation |
#Quality
water.setQualityLevel(level, overrides?): thismethodSwitches tier at runtime and rebuilds only what changed: spectrum size, grid, shaders, FFT, foam field, targets, and the bathymetry bake if its resolution changed. overrides replace single settings, for example setQualityLevel('high', { msaa: 0, ssrSteps: 32 }).
| Property | |
|---|---|
qualityName: QualityLevel | The active tier |
quality: QualitySettings | Its resolved settings, overrides included |
#Sky and lights
water.setSky(sky, opts?): thismethodPlugs in an external sky, read every update(). null returns to the built-in sky and re-adds its dome if addSky. Options: sunIntensityScale (1), moonIntensityScale (1), moonTint, envIntensity (1), syncExposure (true). See Any sky-like object.
water.bindLights(directional?, hemisphere?, opts?): thismethodPoints a DirectionalLight at the water's current key light (sun by day, moon by night) and colours a HemisphereLight from the sky. opts.distance (250) places the light from its target; opts.intensity (1.3) splits colour and intensity. See Sky and lighting.
| Property | |
|---|---|
sky: SkyLike | The active sky: externalSky or builtinSky |
externalSky: SkyLike | null | The sky passed to setSky |
builtinSky: BuiltinSky | Always present |
#Bathymetry
water.setBathymetry(desc): thismethodBakes a seabed from { heightAt(x, z), bounds, resolution?, shoreTrainMinRadius? } so waves shoal, breakers roll up the beach and shore foam follows the coast. null returns to open ocean. See Shorelines.
#Sampling
water.sampleHeight(x, z): numbermethodSurface height at world (x, z), including shoaling and breakers. The horizontal displacement is inverted in 4 fixed-point steps. Gerstner tiers evaluate the spectrum; FFT tiers read the swell cascade back from the GPU (1–3 frames old).
water.sampleNormal(x, z, out?): THREE.Vector3methodCentral differences of sampleHeight at ±0.5 m.
water.isUnderwater(object?): booleanmethodWhether object (default: the camera) is below the surface.
#Buoyancy
water.buoyancy.addObject(object, options?): BuoyancyHandlemethodFloats an object. Options: probes, size: { length, beam }, draft (0), heightSmoothing (2.5), rotationSmoothing, spring (true), tiltSample (0.8), rollJitter (0.012). You keep x, z and the heading; buoyancy writes height, pitch and roll. See Buoyancy and wakes.
water.buoyancy.removeObject(objectOrHandle): voidmethodStops floating an object. handle.enabled = false pauses one instead.
#Wakes
water.addWake(object, options?): WakeHandlemethodTracks a moving object: hull contact foam, a Kelvin V and a persistent trail. Options: length (10), beam (length / 3), headingOffset (0), useVelocityHeading (false). handle.speed is the measured speed in m/s. Up to MAX_HULLS (8) are drawn.
water.removeWake(objectOrHandle): voidmethodFrees the object's wake slot.
#Caustics
water.caustics.patch(material, opts?): materialmethodAdds animated caustics below sea level to a built-in lit material (Standard, Physical, Lambert, Phong, Toon), chaining onBeforeCompile. Options: strength (1), scale (0.11), lightAbsorption (0.25). See Caustics on your materials.
#State and diagnostics
| Property | |
|---|---|
underwater: boolean | The camera is below the surface this frame |
underwaterAmount: number | 0–1, smoothed |
stats | { significantWaveHeight, chop, wind, underwater, sunElevation } |
profiling: boolean | Turn on GPU timing (EXT_disjoint_timer_query_webgl2) |
gpuTimings | Smoothed ms per pass: world, water, overlay, foam, bloom, composite, and fft on FFT tiers |
overlayLayer: number | The layer drawn after the water |
ocean: THREE.Mesh | The ocean mesh in your scene (frustum culling off, follows the camera) |
uniforms | Shared by every water shader. Safe to read |
spectrum, bathymetry, wakes, foam, fft, pipeline | The subsystems. fft is null on Gerstner tiers, foam on low |
#Other exports
BuiltinSkyclassThe analytic sky: sun arc from time, zenith and horizon colours, a cloud deck, stars and moon. new BuiltinSky({ uniforms? }), mesh, sun, sunDirection, moon.direction, fogColor, ambient { sky, ground }, day, apply(params), follow(camera), bindLights(directional, hemisphere, opts), dispose(), and BuiltinSky.createUniforms().
Buoyancyclassnew Buoyancy(surface) works with any object that has sampleHeight(x, z). addObject, removeObject, update(dt), objects.
Wakesclassadd, remove, update(dt), list, and the hullA / hullB uniform arrays the shaders read. MAX_HULLS is 8.
Causticsclassnew Caustics(uniforms), patch(material, opts), and the static Caustics.glsl (the same as CAUSTIC_FN_GLSL) for custom shaders.
WaveSpectrumclassThe Gerstner spectrum shared by the GPU and the CPU: new WaveSpectrum(count), build(U, Lp, windAngle, chopScale), advance(dt), displacement(x, z, att, out), WA / WB uniform arrays, hs, chop, setCount(n).
Bathymetryclassbake(desc, defaultResolution), sample(x, z, out?) → { seabed, dist, dx, dz, train, breaking }, texture, trainTexture (1.1), xform, enabled.
FFTWavesclassThe GPU FFT wave source: new FFTWaves(renderer, { size, cascades }), update(time, { wind, wavelength, windAngle, chop, hs }), sample(x, z, out) from the read-back swell cascade, targets[i].textures[0..1], slopeVariance[i], lambda, cascades[i] (L, rot, kmin, kmax, texel).
| Export | |
|---|---|
PRESETS | Record<string, Partial<WaterParams>>: tropical, sunset, dusk, storm, foggy, moonlit, arctic |
DEFAULT_PARAMS | The defaults every preset fills from. See Water parameters |
getPresetParams(preset) | Complete, deep-cloned params for a name or partial object. Throws on an unknown name |
QUALITY_LEVELS | See Quality and performance |
CAUSTIC_FN_GLSL | caustic(uv, t), causticRGB(worldPos, refrSun, t, scale) |
SKY_GLSL | Sky uniforms plus skyBase(d), skyColor(d, withDisc), envReflect(d), hazeColor(d). Include NOISE_GLSL first |
NOISE_GLSL | sk_hash, sk_noise, sk_fbm, safeNormalize2 |