Cold Start
README.md
asc_dunefield
ASCENSION's dune sea — everything solid in the finale. It replaces asc_terrain,
whose four ridge bands were the retired sunset valley.
Four pieces of geometry. One deforming field: a 224 × 224 grid over 1400 world
units (50 176 vertices, ~99 k triangles) whose positions and normals are written
every frame by asc_dune.computeShader, a kind: vertices pass. Three static
parallax ranges at z = −880 / −1500 / −2400, silhouettes with no deform cost and
no shadow cast, because a 1400 unit field ends at a visible edge and the horizon of
a dune sea has to be dunes. And the playa they all stand on, a 9000 unit plane
half a unit under the field's tapered rim, so the horizon is the real horizon
rather than the field's own boundary.
The deform's height law is the sum of four terms and a pure function of the clock
bus: transverse dunes with a gentle windward ramp and a steep lee slip face; the
migration of that whole train downwind by windAccum × CREST_RATE; scour
lowering and rounding the crests as the storm planes them off; and the tornado's
passage, swept along the 24-sample ground track up to torTrackN as a trench with
twin berms and radial rake. There is deliberately no accumulation buffer — the
director seeks constantly, and an accumulator would make every seek a different
desert and a held reveal frame irreproducible.
Across t 26.25 → 29.0 the field is driven flat inside TYPE_PAN
(x −170…170, z −250…−60) with a 24 unit feathered edge, on aux.typeReveal. That
is FINISH's stage; this module builds it and does not draw the letters.
The one named cross-lane resource
ctx.data.duneHeights is the handle of the f32 buffer the deform pass writes its
heights into, and ctx.data.duneHeightsMeta is { n, w, cell }. The tornado sites
its base on the deformed sand and the storm lifts its grains off the real crests by
reading those two, rather than duplicating this module's noise and drifting from
it. Vertex i is iz * n + ix.
Checking it
M.check(st) answers the two questions a deform pass has to answer about itself
from the engine rather than from prose — renderer.mesh.boundsSource(guid) reports
"compute" once a pass has written the vertices, and ref:status() reports
whether the dispatches actually ran, since a dispatch call returning true means
queued. M.sampleHeights(st) starts a readback of the heights buffer.
Bus scalars it reads
windDir windStr windAccum scour aux.torTrack aux.torTrackN
aux.typeReveal aux.quality worldLight visRange aux.skyHorizon
aux.skyVoid skyMix aux.sceneExposure. It does not read gust: a dune does
not wobble at 3 Hz.