Guides
Sky and lights
The water needs to know where the sun is and what the sky looks like. By default NatureGL River brings its own simple sky and drives your lights, fog and exposure from the preset. Hand it an external sky and it follows that instead.
#The built-in sky
With builtInSky: true (the default), create() adds an analytic sky dome to your scene. The preset's light block drives it:
| Param | What it sets |
|---|---|
elevation, azimuth | Sun angles in degrees. Azimuth 0 is toward −z, 90 toward +x |
sunColor, sunIntensity | Sun colour and the DirectionalLight intensity |
skyTop, skyHorizon | The dome gradient, also used in the water's reflections |
clouds, stars | Soft clouds and a star field on the dome, 0 – 1 |
hemiSky, hemiGround, hemiIntensity | The HemisphereLight |
fogColor, fogDensity | The scene's FogExp2 |
exposure | renderer.toneMappingExposure |
lightAmount | Scales the water's in-scatter and foam brightness. Low at night, so dark water stays dark |
The system owns fog, exposure and tone mapping unless you opt out:
const water = await RiverSystem.create({
renderer, scene, camera,
manageFog: false, // leave scene.fog alone (a Fog or FogExp2 you set is still respected by the water)
manageExposure: false, // leave renderer.toneMappingExposure alone
manageToneMapping: false, // don't switch NoToneMapping to ACESFilmicToneMapping
});The water shader reads whatever fog the scene has, THREE.Fog or THREE.FogExp2, so the surface fades the same way your geometry does.
#Bind your lights
water.bindLights(sun, hemi, 120);
sun.target.position.copy(focusPoint); // move the target yourself, e.g. with the cameraOn every update() the system sets the directional light's colour and intensity from the preset and puts it distance metres from its target along the sun direction. It also sets the hemisphere light's colours and intensity. Both arguments are optional; pass null to skip one.
Shadows stay yours. Configure sun.castShadow and the shadow camera as usual. The demo uses a 2048² map over ±55 m that follows the orbit target.
water.lighting holds the current values if you want to drive something else, such as a lens flare or a sound:
const { sunDirection, sunColor, sunIntensity, hemiSky, hemiGround, hemiIntensity,
fogColor, fogDensity, exposure } = water.lighting;morning: a low warm sun at 17°golden: 7°, long lightdusk: 2.5°, the first starsnight: moonlight at 0.45#Use an external sky
setSky(sky) takes any object with these optional fields. They are read by reference on every frame, so a live sky can keep changing them.
| Field | Type | Used for |
|---|---|---|
sun.direction | Vector3 | Glints, in-scatter, caustics, foam light |
sun.color, sun.intensity | Color, number | The same, in DirectionalLight units |
envMap | equirect Texture | Sky reflections, instead of the built-in gradient |
envIntensity | number | Scales envMap (default 1) |
cloudShadow | { texture, matrix } | The matrix maps world position to shadow UV, and .r is the light factor. Dims glints, in-scatter and caustic reflections |
fogColor | Color | Fog and the reflection's horizon colour |
skyColor | Color | The top of the reflected sky when there is no envMap |
water.setSky({
sun: { direction: mySunDir, color: mySunColor, intensity: 3 },
envMap: myEquirectTexture,
fogColor: myFogColor,
});
water.setSky(null); // back to the built-in skyWhile an external sky is set, the built-in dome is removed from the scene and bound lights are not driven: the sky that owns the sun owns your lights too. Any field you leave out falls back to the preset. Fog density and exposure still come from the preset unless you turn off manageFog or manageExposure.
NatureGL Sky's SkySystem has all of these fields except skyColor. See With other packs.