Start here
Installation
NatureGL Water ships as a folder with a runnable demo, the library source, and a prebuilt ES module with TypeScript declarations. Pick the integration path that suits your build.
#Requirements
| three.js | >= 0.180 as a peer dependency. Developed and tested on r186. The library never bundles it |
| Renderer | THREE.WebGLRenderer with WebGL2. There is no WebGPU or TSL path |
| Camera | THREE.PerspectiveCamera. Logarithmic depth buffers are not supported |
| FFT tiers | EXT_color_buffer_float. Without it, high and ultra fall back to Gerstner waves |
| Node | 18 or newer, only for the demo and the build scripts |
#Run the demo first
#Install
cd naturegl-water
npm install#Start the dev server
npm run devIt opens http://localhost:5182/demo/: a tropical island with ships, a dock, a wreck and a reef. The demo page lists every control.
#Build or test (optional)
npm run build # library -> build/, static demo + examples -> dist/
npm test # headless real-GPU smoke test: every preset -> test-results/*.png + fps| Script | What it does |
|---|---|
npm run build:lib | build/index.js (+ source map) with three external, then tsc writes build/*.d.ts |
npm run build:demo | Static demo and examples into dist/ |
npm run build | Both |
npm run preview | Serves dist/ |
npm test | Headless smoke test on the real GPU |
#What's in the folder
├── src/the library: no DOM, no scenery│ ├── WaterSystem.jsthe facade: create, update, render, presets, sampling│ ├── core/wave spectrum, ocean grid, bathymetry, foam field│ ├── fft/the GPU FFT wave source│ ├── effects/buoyancy, wakes, caustics│ ├── post/the render-target pipeline│ ├── sky/the built-in sky│ ├── shaders/GLSL as template strings│ └── config/QualityLevels.js, presets/├── build/prebuilt ESM bundle + .d.ts├── demo/the full demo app (island, ships, reef)├── examples/basic/minimal Vite integration├── examples/cdn/plain JS + import map├── examples/external-sky/a hand-made sky object plugged in with setSky()├── examples/with-sky/with a real naturegl-sky SkySystem├── examples/lagoon/shore-wave stress test└── scripts/smoke.mjs and dev helpers
#Add it to your project
Copy build/ into your project, for example as lib/naturegl-water/, and import from it. three stays an external import, so your bundler or an import map resolves it.
import { WaterSystem } from './lib/naturegl-water/index.js';index.d.ts next to it gives editors full types.
src/ is plain ES modules with JSDoc and no build step. GLSL lives in src/shaders/*.glsl.js as template strings.
import { WaterSystem } from './vendor/naturegl-water/src/index.js';Choose this if you want to read or change the shaders.
Keep the package anywhere and point an alias at the source. The demo imports the library this way.
import { resolve } from 'node:path';
import { defineConfig } from 'vite';
export default defineConfig({
resolve: {
alias: { 'naturegl-water': resolve(import.meta.dirname, 'path/to/naturegl-water/src/index.js') },
dedupe: ['three'],
},
});import { WaterSystem } from 'naturegl-water';#Without a bundler
An import map resolves three from a CDN. The library comes from your copy of build/.
<script type="importmap">
{ "imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.186.0/build/three.module.js",
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.186.0/examples/jsm/"
} }
</script>
<script type="module">
import * as THREE from 'three';
import { WaterSystem } from './lib/naturegl-water/index.js';
</script>examples/cdn/index.html is a complete page. Serve the package root with any static server, such as npx http-server ., and open /examples/cdn/.