# Terrain surface maps

Ski detail update: `snow-detail-color.jpg` and `snow-detail-normal.png` are the
original 2048×2048 Diffuse and OpenGL normal maps from the same Poly Haven Snow 02
asset by Rob Tuytel (CC0). Reproduce with `sh tools/assets/prepare-ski-detail.sh`.
Only ski loads these: the 2K normal replaces its old 512px normal and the colour
map adds one texture, approximately 41.3 MiB additional RGBA8 GPU storage with
mips versus the former ski maps. The scan is used at two rotated scales with
anisotropy 8; it changes shading only. Other disciplines retain the 512px maps.

CC0 images downloaded directly from Poly Haven, resized to 512×512 PNG:

| Files | Source / author |
|---|---|
| asphalt-color, asphalt-normal | https://polyhaven.com/a/asphalt_01 — Charlotte Baglioni (photography), Dario Barresi (processing) |
| snow-normal | https://polyhaven.com/a/snow_02 — Rob Tuytel |
| rock-color | https://polyhaven.com/a/rock_boulder_cracked — Dimitrios Savva (photography), Dario Barresi (processing) |

License: https://polyhaven.com/license
Reproduce: `sh tools/assets/prepare-surfaces.sh` (curl and macOS sips).
Only images are used, no external model geometry or code.

Colour maps are sRGB; OpenGL normal maps are linear. Repeat wrapping, mipmaps,
anisotropy 4. Each terrain owns its textures and disposes them on course unload.
Ski/wingsuit load two maps (~2.67 MiB RGBA8 with mips); longboard loads three
(~4 MiB). No displacement or extra material draw calls. Fine detail fades with
view distance, keeping the existing macro terrain structure and gameplay height.

The road uses the intact aggregate of Asphalt 01 at its 2.1 m scan scale, with
a second colour sample to soften repeated stains. No crack overlay or displacement.

## Terrain material layers

On ski, wingsuit and longboard, `rock-color` (with the forest `rock-color`,
`litter-color`/`litter-normal` and `snow-detail-color`/`snow-normal`) is no longer bound
as its own sampler: `src/world/terrain-layers.js` packs them on a worker into two
512×512×4 RGBA8 texture arrays (albedo ratio + height, normal), about 11.2 MiB with mips,
built once per session and shared by every leg. The mtb forest keeps its own maps.
`?layers=0` restores the old per-map path for A/B. Candidate CC0 replacements are listed
in `tools/assets/prepare-terrain-layers.sh` (not run; downloads need approval).
