Module motion_vector

Module motion_vector 

Source
Expand description

Motion-vector grid pass.

MD2 draws a grid of n_x × n_y short line segments into the warp output every frame. The renderer is stateless — segments live for exactly one frame, painted at the same screen-space grid each time — but because the segments end up inside the feedback loop (we dispatch between the shape overlays and the blur pyramid), the warp pulls them into trails. Those trails are the “motion vectors” the player sees.

The grid is clamped to MD2’s hard cap of 64 × 48; combined with the 2 vertices per segment that gives MAX_MOTION_VECTOR_SEGMENTS * 2 vertices per frame upload — small enough to keep the buffer at a static size.

Segment geometry per cell (i, j):

  • Anchor: (x, y) = ((i + 0.5) / n_x + dx, (j + 0.5) / n_y + dy) in MD2 preset space [0, 1] (origin top-left), then mapped to clip space with preset_xy_to_clip.
  • Tail: anchor + (length / n_x, 0) — a small horizontal segment. length is mv_l (MD2 default 0.9) expressed in cells so a value of 1.0 would span an entire cell, with the visible trail length emerging from how aggressively the feedback warp pulls it.

Structs§

MotionVectorRenderer
GPU pass for the MD2 motion-vector grid.
MotionVectorVertex
One vertex of the motion-vector stream. Two per segment (head + tail). Pure passthrough — the shader doesn’t transform or shade, just emits the per-segment colour.
WarpField
Per-vertex warp-displacement field, borrowed from the renderer’s most recent update_warp_vertices call. vertices[r * cols + c] matches the warp mesh’s row-major layout; the segment builder recovers uv_orig from pos_clip (inverse of the same mapping WarpMesh::new uses) and reports the displacement uv_warp - uv_orig at the grid cell’s nearest mesh vertex.

Constants§

MAX_MOTION_VECTOR_GRID_X
Maximum cells along each axis. MD2 caps motion-vector grids at this size in the preset format; the renderer enforces the cap regardless of what the preset declares.
MAX_MOTION_VECTOR_GRID_Y
MAX_MOTION_VECTOR_SEGMENTS
Maximum number of segments stored in the GPU buffer.

Functions§

build_segments 🔒
Build the per-frame segment list. Pulled out as a free function so it can be unit-tested without a GPU device. When warp_field is Some, segments point along the local warp displacement; without it the function falls back to a horizontal stub.
preset_xy_to_clip 🔒
MD2 preset-space → clip-space, identical to the helpers in custom_wave / custom_shape. Origin moves from top-left at (0, 0) to centre at (0, 0), range [0, 1] becomes [-1, 1], and y is flipped.
sample_warp_displacement 🔒
Look up the warp displacement at preset-space position (x, y) from field. Bilinear-interpolates across the four nearest mesh cells so the segment direction stays smooth across the grid boundaries. Returns (dx, dy) in preset-space UV units (uv_warp - uv_orig).