Surface shading
Reflection follows a physical dielectric Fresnel curve set by a single index-of-refraction value. The sky bakes to an environment map each frame and the water takes its colour from it, with subsurface scattering through the crests.
Everything on this page was rendered by Tidewater in a browser: the waves, the sky, the boats, the light. WebGPU first, with a WebGL2 fallback.
Take the camera under and the scene holds up: Snell's window overhead, caustics on the sand, god rays through the fog, marine snow drifting past.
Boats write their wake into the water itself. The surface bends around the trail, whitecaps seed along it, and the sea slowly forgets.
The surface is three FFT cascades covering everything from 16 m wind chop to 256 m open-ocean swell, with Gerstner swells layered on top. A CPU mirror evolves the same spectrum, so a hull rests on the exact surface you see, with no GPU readback.
Tessendorf evolution, Phillips spectrum, and a foam channel gated on the wave Jacobian: whitecaps break where the face steepens, not where a noise texture happens to be white.
One dial runs the whole day. Sun, sky, fog, reflections and water colour follow it, and every preset keeps its character at 3 am.
Click the water and rings spread from the impact. Hulls stamp their own as they cross crests, and River mode drifts everything downstream.
Reflection follows a physical dielectric Fresnel curve set by a single index-of-refraction value. The sky bakes to an environment map each frame and the water takes its colour from it, with subsurface scattering through the crests.
Whitecap foam gates on the FFT Jacobian, wake foam stamps from the boat's path, and shoreline foam radiates from rocks and pilings. Presets swap the textures and coverage.
Pass a hull into new Buoyancy(ocean, mesh, {points})
and it tracks the rendered surface. Multi-point sampling gives
pitch and roll; a single point is enough for buoys and debris.
Every v1.x update is free for existing buyers. Here's what landed since launch.
syncToTick(n) puts every client on the same wave,
with no state to sync.
loadPreset() and a
per-frame debug readout.
Each preset sets its own waves, foam, sky, fog, water tint, seabed, audio and props: ice floes in Arctic, kelp and coral in Reef, a flow direction in River.
The runtime picks a tier from the backend, pixel budget and
hardware, and sheds features instead of frames when the budget
runs out. Override with ?quality=low|med|high|ultra.
Tidewater ships as plain ES modules behind an import map: one
script tag in any page, no bundler. The
<water-canvas> web component gives
non-Three.js sites a self-contained ocean. TypeScript
declarations and the handbook are
included.
// 1. import map — once, in your HTML <script type="importmap">{ "imports": { "three": "https://cdn.jsdelivr.net/npm/three@0.184.0/build/three.module.js", "three/webgpu": "https://cdn.jsdelivr.net/npm/three@0.184.0/build/three.webgpu.js", "three/tsl": "https://cdn.jsdelivr.net/npm/three@0.184.0/build/three.tsl.js", "tidewater/": "./tidewater/" } }</script> // 2. instantiate the ocean and start rendering import { OceanFFT } from "tidewater/OceanFFT.js"; import { SEA_MODES } from "tidewater/SeaModes.js"; const ocean = new OceanFFT(camera, sun); ocean.applyMode(SEA_MODES.reef); scene.add(ocean); // 3. or drive everything through the WaterSystem façade import { createWaterSystem } from "tidewater/WaterSystem.js"; const water = createWaterSystem({ ocean, scene, camera, renderer }); water.waves.setChoppiness(0.6).setIor(1.34); water.loadPreset("hurricane");
Every v1.x release ships to existing buyers at no charge. A future v2 would be a paid upgrade, but you keep v1 forever.
Both. Tidewater is WebGPU-first: the FFT cascades, post pipeline and TSL graph compile directly to compute and fragment passes. On browsers without WebGPU, the same TSL graph is lowered to WebGL2. The look holds. You lose some compute-shader speed, and a few Ultra-tier features get capped.
r184 is the tested minimum. Tidewater is unbundled, so you control the Three.js version via your import map. WebGPU and TSL still shift between Three releases. Pin a version you've verified.
Yes. The Tidewater License is per-developer. Use it in client projects, games, sites, embedded apps, paid or free. You can't redistribute the source. Read the full terms before purchasing.
Open the live demo on the actual device. Tidewater targets modern desktop and laptop GPUs first. Phones and tablets fall back to the Low and Med tiers, which the demo picks automatically. When the budget runs out, the runtime sheds features instead of crashing: SSR off on Low, one FFT cascade on phones, cloud branch removed from the sky shader at Low.
Once the .zip has been downloaded, all sales are final. Before download, you can request a full refund within 7 days for any reason. Email me.
A versioned .zip. Inside: the src/ module tree this site is built against, the assets/ bundle (CC0 boat, dock, ship, rock, yacht and trawler GLBs plus normal and foam textures), TypeScript declarations, an example index.html, a copy of the docs, and a manifest.json recording the version. Any version you've previously bought is re-downloadable from your purchase page.
No. Tidewater is sold only through this site. The zero-build CDN setup avoids the npm and bundler hop entirely. If your toolchain expects an npm install, file links inside a local directory work fine.
One payment, per developer. Every v1.x update is free, commercial use is covered by the license, and you can get a full refund within 7 days, up to the point you download the zip.
Instant download: source tree, CC0 assets, TypeScript declarations, docs and an example page.