NatureGL Waterv1.1.0

naturegl-water v1.1.0

An ocean for the scene you already have

A wind-driven ocean for three.js WebGLRenderer. Waves come from a GPU FFT or a Gerstner sum, the water refracts and absorbs light by its real thickness, breakers roll up any seabed you bake, boats float and leave wakes, and the camera can dive straight under the surface.

$ npm install && npm run dev

#Your scene, with water in it

WaterSystem adds one ocean mesh and a sky dome to your scene and draws it with your camera. update(dt) advances the waves, foam, buoyancy and wakes. render() draws your scene into an HDR target with depth, puts the water over it, and tone-maps to the canvas.

Follow the quick start or see how it composes with NatureGL Sky.

Half in, half out at the waterline, then down to the reef. It is the same ocean seen from below, with Snell's window, light shafts and caustics on the seabed.
presets, one file each
7
quality tiers, low to ultra
4
high tier, Apple M5, 1280×720 uncapped
~140 fps
hulls with wakes at once
8

#What's in the box

#Seven seas, ready to load

Every preset is a plain params object in src/config/presets/. Load one with loadPreset, change a few values with setParams, or save your own with getParams().

TropicaltropicalClear afternoon over a turquoise reef shelf.
SunsetsunsetLow sun, a long glitter path and warm haze.
StormstormGale-force wind, long swell and breaking whitecaps under a dark deck.
FoggyfoggyCalm grey morning, visibility a few hundred metres.
MoonlitmoonlitNight sea lit by the moon and stars.
ArcticarcticCold, steel-blue water and a fresh breeze.

See all seven presets

#A floating raft in thirty lines

main.js
import * as THREE from 'three';
import { WaterSystem } from 'naturegl-water';

const renderer = new THREE.WebGLRenderer();   // leave toneMapping at NoToneMapping
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(55, innerWidth / innerHeight, 0.3, 12000);
camera.position.set(0, 7, 26);

const water = await WaterSystem.create({ renderer, scene, camera, preset: 'tropical' });
const sun = new THREE.DirectionalLight(), hemi = new THREE.HemisphereLight();
scene.add(sun, sun.target, hemi);

const raft = new THREE.Mesh(
  new THREE.BoxGeometry(3, 1, 5),
  new THREE.MeshStandardMaterial({ color: 0xf0ad4e }),
);
scene.add(raft);
water.buoyancy.addObject(raft, { size: { length: 5, beam: 3 }, draft: 0.2 });

const timer = new THREE.Timer();
renderer.setAnimationLoop(t => {
  timer.update(t);
  water.update(timer.getDelta());   // waves, sky, buoyancy, wakes, foam
  water.bindLights(sun, hemi);      // your lights follow the sky
  water.render();                   // scene -> HDR + depth -> water -> bloom -> ACES
});

#Weather that changes while you watch

From tropical to storm in twelve seconds by easing wind, wavelength, clouds and the water optics. Significant wave height goes from 0.85 m to about 6 m.

#Part of the NatureGL series

NatureGL Water reads its light from a sky. It has its own built-in sky, and setSky() plugs in NatureGL Sky's SkySystem or any object with a sun, an environment map and a fog colour. NatureGL Island builds its sea on it.