# pan_surface
Every hard surface on the salt flat, from one shader: the crust, the pan under
and beyond it, the runway and apron concrete, the painted markings, the hangar's
corrugated sheet, the marker posts and the tie-down rings.
It declares **no texture slots**. Every pattern is a function of
`input.world_position`, so the material's texture budget and group 0's sampled
textures are untouched, and there is nothing here for a texture pipeline to get
wrong.
## What `mode` selects
| `mode` | Lattice | Used by |
|---|---|---|
| 0 | jittered voronoi over world XZ, at two plate sizes, plus salt glint | `gs_pan_crust`, `gs_pan_ground` |
| 1 | rectangular slab grid over world XZ, plus aggregate | `gs_pan_concrete`, `gs_pan_apron`, `gs_pan_paint` |
| 2 | corrugated sheet — ribs, panel seams, run-down streaks | `gs_pan_hangar` |
| 3 | painted — grain and macro mottle only | `gs_pan_marker`, `gs_pan_ring` |
## The three things worth knowing before changing it
**`wetness` is the film's arc, and it is written every frame.** It runs 0..1 and
carries every mode from its dry colour and roughness to its wet ones, with the
CRACKS reaching wet first — water stands in the low ground before it stands on
the plates. The pan slice writes it from `Film`; nothing else should.
**Detail fades on the SCREEN-SPACE FOOTPRINT, not on distance.** `fw` is how
many metres of surface one pixel covers, from the derivative of the world
position. A camera 28 cm above a ground plane sees it at 8 m under an angle
where one pixel spans metres, and any pattern finer than that becomes moire —
which is exactly what the salt grain did while looking correct at 1 m and again
at 40 m. This film also cuts between a 16-degree and a 78-degree lens, so no
hand-tuned distance would hold across both. Every octave, the glint and the
corrugation each gate on `fw` against their own feature size, and the
`*_fade` properties are a second, author-facing ceiling on top.
**The hashes are integer bit-mixes, not `fract(sin(dot(...)))`.** The pan is
7.2 km across and the finest layer divides a metre into sixty, so a cell index
runs to a few hundred thousand. At that magnitude a sine-of-dot-product is
quantised by f32 into a regular lattice, and the grain came out as a diagonal
corduroy weave over the whole near field. A bit-mix over the integer cell index
is exact everywhere in this world. Seed offsets are therefore WHOLE numbers of
cells — a fractional one names the cell the hash already answered for.