# Open Ocean — Three.js WebGPU + TSL

A single-file (`index.html`) open-ocean scene with no build step. It uses Three.js r186 (`WebGPURenderer` + TSL) loaded from the jsDelivr CDN.

- **Waves:** 16 Gerstner waves are summed on the GPU in the vertex shader. Their amplitudes follow a Pierson–Moskowitz spectrum driven by wind speed. The fragment shader recomputes the analytic normals and adds 8 small detail waves that only affect normals.
- **Foam:** appears where the surface compresses, i.e. where the Jacobian of the horizontal displacement drops. It is broken up by a procedural foam texture. A ring of foam also forms around the buoy.
- **Sky:** an analytic sky with a sun and drifting clouds. The same sky function supplies the Fresnel reflection on the water. The water also has a sun glint and sub-surface scattering through the wave crests.
- **Buoy:** a rigid body floating on the waves. The same wave function runs on the CPU, and buoyancy is sampled over 9 water columns under the hull, giving heave, pitch and roll. Drag pulls it along with the water's orbital motion, and a slack mooring keeps it in place.
- **Backend:** uses WebGPU when available and falls back to the WebGL 2 backend automatically. The badge in the panel shows which one is active.

## Running

Serve the folder with any static server and open it:

```
python3 -m http.server 8000
# then open http://localhost:8000/
```

## Controls

| Input | Action |
|---|---|
| **Wind speed** slider (2–26 m/s) | Moves the spectral peak: stronger wind gives longer, higher waves and more whitecaps. The label shows the Beaufort number. |
| **Wave height** slider (×0.1–2.5) | Scales all wave amplitudes. The label shows the resulting significant wave height Hs. |
| **Choppiness** slider (0–2) | Horizontal Gerstner displacement: sharper crests, flatter troughs and more crest foam. |
| Left-drag / one-finger drag | Orbit the camera. This overrides the slow auto-orbit. |
| Scroll / pinch | Zoom. |
| Idle for 4 s | Auto-orbit resumes. |

Slider changes are eased in over about a second, so the sea state changes smoothly.

### URL options

- `?webgl` — force the WebGL 2 fallback.
- `?wind=15&height=1.5&chop=1.2` — set the starting slider values.
- `?fixedres` — turn off adaptive resolution. By default, the pixel ratio drops step by step if the frame rate stays below about 52 fps, so the scene holds 60 fps on weaker laptop GPUs.
