# Millbrook Pond

A calm countryside pond diorama in Three.js. A timber watermill with a turning waterwheel, a plank dock, an arched footbridge over the brook, and a rowboat with someone fishing, all around a reflective, refractive pond. Everything is generated in code. There are no external models, textures or HDRIs, and three.js r169 loads from jsDelivr.

## Running

There's no build step, but ES modules need to be served over HTTP:

```sh
python3 -m http.server 8000
# open http://localhost:8000/index.html
```

## Controls

| Action | Mouse / trackpad | Touch |
| --- | --- | --- |
| Orbit the pond | drag | one-finger drag |
| Zoom | scroll | pinch |
| Make ripples | click the water | tap the water |

The camera orbits slowly on its own. The small pill in the bottom-right corner has:

- **⏸ / ▶** pauses or resumes the automatic orbit.
- **Afternoon · Golden · Dusk** blends to that time of day over a couple of seconds (sun, sky, fog, water tint, shadows). At dusk the mill windows and dock lantern light up and fireflies come out.

## Capture mode

Open `index.html?capture=1` to get:

- no UI (title, hints, controls and cursor are hidden) and no user input,
- a scripted **12-second camera move**: one full orbit around the pond that swoops low across the water and back up. Every term in the path is periodic, so the clip ends exactly where it started and loops seamlessly. It repeats every 12 s, so you can record any 12-second window.
- motion timed to the loop: the waterwheel turns exactly once per 12 s, and the boat's drift and bob use periods that divide 12 s.

Optional query parameters (they also work outside capture mode):

- `tod=afternoon|golden|dusk` sets the starting time of day, e.g. `index.html?capture=1&tod=golden`.
- `at=<seconds>` starts the clock at that time, which is useful for previewing a particular frame of the capture move.
- `fixed` turns off the adaptive resolution scaling.

`window.millbrook.time` shows the current scene time, and `window.__ready` turns true once the first frames have rendered.

## How the water works

The pond surface is one custom shader (`src/water.js`) that combines:

- **Planar reflection**: a mirrored camera renders the scene (mill, trees, sky, clouds) into a half-resolution render target, clipped at the waterline.
- **Refraction**: a second pass renders only the submerged layer (pond bed with animated caustics, posts, paddles, rocks) and samples it with normal-based distortion.
- **Depth tint**: a heightmap of the analytic terrain gives the water depth at each pixel. View-dependent absorption takes the colour from clear, sandy shallows to a dark centre.
- **Fresnel blending**, sparkling sun glints, shoreline foam lace and distance fog.
- **Wind ripples**: three scrolling layers of a tileable, procedurally generated gradient-noise normal map.
- **Dynamic ripple rings**: up to 40 analytic wave packets that spread and fade. They come from the waterwheel paddles, the bobbing boat, the fishing float (plus bites), rising and jumping fish, landing dragonflies, wheel drips and your taps. The wheel also churns the water around it and leaves a foam trail.

## Performance

The app targets 60 fps on laptops and 30 fps or more on mid-range phones:

- Instanced foliage, merged vertex-coloured geometry, and flat-shaded Lambert materials.
- Half-resolution reflection and refraction targets. The shadow map is updated once per frame.
- Grass, flowers and particles are skipped in the mirror pass.
- Touch devices get a lighter preset: fewer instances, a smaller shadow map, a lower pixel ratio and no MSAA.
- An adaptive pixel-ratio controller steps resolution down if frames run long, and back up when there's headroom.

## Files

- `index.html`: page, import map, UI
- `src/main.js`: renderer, camera and controls, time of day, boat and angler animation, capture mode, render loop
- `src/common.js`: noise, analytic pond, brook, path and mill layout, geometry builder, wind-sway shader hook
- `src/terrain.js`: terrain mesh, pond-bed heightmap, noise texture, caustics
- `src/water.js`: water shader, reflection and refraction passes, ripple buffer
- `src/sky.js`: gradient sky, clouds, time-of-day presets
- `src/props.js`: mill cabin, waterwheel, dock, footbridge, rowboat and angler
- `src/nature.js`: trees, bushes, rocks, reeds, cattails, grass, flowers, lily pads, drifting leaves
- `src/life.js`: particles (smoke, drips, splashes, fireflies), dragonflies, birds, fish
