Skip to main content

Module warp_mesh

Module warp_mesh 

Source
Expand description

Warp mesh: a per-vertex UV grid that resamples the previous frame (ADR-0113).

§What it generalizes

ADR-0048 gave the engine one affine transform through which an accumulation reads its own past: a single zoom, rotation and translation applied identically to every texel. This scene is that transform per vertex. The frame is covered by a grid of cells; each of its vertices carries its own zoom/rot/cx/cy/dx/dy/ sx/sy/warp, and the rasterizer interpolates between them — so the past can spiral in one corner and drift in another, which no single affine can express.

Those nine outputs come from a preset’s [per_vertex] table, whose bindings are evaluated once per vertex per frame with x, y, rad and ang bound to that vertex’s own position. A preset that declares no such table gets the scalar params of the same names applied everywhere, which is exactly ADR-0048’s single shared transform — so the idiom degrades to the one it generalizes.

§The grid is a resolution, not a shape

ADR-0037, and this is the most likely place in the engine to get it wrong, because here the grid is user-visible: a preset names [mesh] x and [mesh] y, and they are quantized and clamped to a tier capacity. Every screen-destined coordinate here takes its aspect from the render target — the rad/ang the per-vertex program reads (computed in vertex_position), and the isotropic space the source-uv transform works in (computed in the vertex shader from a uniform the CPU fills with the target’s aspect). meshx/meshy appear in neither. A f32 aspect derived from the mesh size would be the bug.

§Three passes

  1. warp — the mesh is drawn into the write half of a ping-pong field, sampling the read half through each vertex’s source uv and scaling it by decay^dt. This is the only pass that is not fullscreen.
  2. deposit — a fullscreen pass adding this frame’s light onto the warped past: a palette-coloured gaussian ring with optional angular arms. It runs after the warp, so the light it lays down is “now” and is warped from the next frame onward.
  3. present — a fullscreen pass compositing the field over the backdrop, premultiplied (ADR-0026), scaled by brightness and occlude.

All three rates are per second (ADR-0019): decay, zoom, sx, sy are factors per second and rot/dx/dy/warp/deposit are amounts per second, so the look is identical at 60 Hz and 144 Hz.

GPU resources are built lazily on first render, for the reason reaction_diffusion.rs documents: a capture that never activates this scene never builds this scene’s pipelines, so it cannot perturb another scene’s render on the DX12 WARP software adapter.

Modules§

draw
What MilkDrop draws between the warp and the composite (Plan 0100 Phase 4): the waveform, the custom waves and shapes, the two borders, and the motion-vector grid.

Structs§

WarpMeshScene
The warp mesh scene (ADR-0113).

Constants§

COMPOSITE_PARAMS
MilkDrop’s composite roster, in the order COMPOSITE_PARAMS declares it — the six flags and one multiplier its format carries, reachable from a preset and written by a converted bundle’s per-frame program.
DEFAULT_MESH
The grid a [mesh] table’s absent keys mean. Coarse enough to be free on any machine and fine enough that a rad-driven program reads as a curve rather than as facets.
MAX_MESH
The largest grid any tier may name, in cells — the .milk format’s own ceiling (meshx <= 128, meshy <= 96), so a converted preset’s requested grid is always representable.
MAX_SHAPE_VERTICES
The most vertices the filled-shape buffer holds.
MILKDROP_SOFTNESS
The softness every warp_mesh stroke is drawn at — the waveform, every custom wave, every shape outline, both borders and the motion grid, which all reach the line fragment through one LineRenderer::draw_split call.
MIN_MESH
The smallest grid a [mesh] table may name, in cells. Below two the mesh is a single quad and the per-vertex program has no interior to interpolate.
PARAMS
Parameter vocabulary — see fragment_field::PARAMS. Keep in sync with set_param below.
PER_VERTEX_PARAMS
The nine outputs a [per_vertex] table may bind, in the order this scene stores them. Keep in step with PER_VERTEX_DEFAULTS and WarpMeshScene::set_per_vertex.

Functions§

clamp_grid
Clamp a preset’s requested grid into what tier will carry.
vertex_count
How many vertices a grid of mesh cells has. One more than the cell count on each axis — the fencepost the whole per-vertex path is sized by.
vertex_position
The (x, y, rad, ang) a vertex’s [per_vertex] bindings are evaluated against, for the vertex at column col, row row of a mesh grid, on a render target of aspect aspect.