Skip to main content

Module draw

Module draw 

Source
Expand description

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.

§It is CPU geometry, deliberately

Every figure here is a handful of hundreds of points produced by a program the preset wrote, so it is built on the render thread into two reused buffers and handed to the GPU as one line batch and one triangle batch. Nothing here allocates per frame: both buffers are sized once at preset load from the bundle’s own counts, which are bounded by MAX_WAVE_POINTS and its siblings.

§Two blend modes, and why the geometry is ordered

MilkDrop chooses per element: bAdditiveWaves and a custom element’s own additive pick between dst = src + dst and dst = src*a + dst*(1-a). Both are honoured here, by partitioning each buffer — additive producers first, over-blended ones after — and handing the split index to the two-pipeline draw (LineRenderer::draw_split).

Reading both as additive is what saturated the frame to flat colour inside half a second, and it is not a small error: an additive seam sums where alpha-over replaces, so N overlapping producers land at N rather than at ≤ 1. That bites hardest on the 28.5 % of the corpus that sets fDecay >= 1.0 (2 949 of 10 347, measured 2026-08-16), where the field is a perfect integrator and nothing brings the sum back down.

The order within each half is the order MilkDrop draws in — waveform, custom waves, custom shapes, borders, motion vectors — because an over-blended stroke must land on top of what it covers.

§The coordinate space, once

MilkDrop places everything in uv: 0..1 across the frame with y = 0 at the top. The shared line renderer takes world space: y in -1..1 bottom-to-top, x in -aspect..aspect (its shader divides x by the aspect). uv_to_world is the one conversion, and every producer below goes through it — which is what makes a figure round on any display and is the ADR-0037 rule applied to geometry rather than to a grid.

§What is approximated, stated

  • A dot is a very short segment with both caps extended. wave_usedots draws points; the line renderer draws quads between endpoints, and its falloff runs across the stroke only — so a short segment is round because both endpoint extensions push the quad past it by the half-width (ADR-0158), not because it is short. Without them it is a sub-pixel dash; see dots.
  • wave_mystery means something different in every mode, which is the reference’s own design rather than a simplification here.
  • Mode 6 and 7’s line does not drift. Its angle is wave_mystery alone; a time * 0.05 term rotates it a full turn every ~126 s, which a Plan 0109 Phase 2 look gate rejected against Blur Mix 3’s horizontal reference traces. Listed here because the reference’s own mode 6 is documented only as “a line”, and “which line” is a reading of it — see the arm’s comment.

Structs§

DrawGeometry
The two buffers a frame’s draw layer fills, each partitioned by blend mode. Sized once at preset load.
Exposure
What one frame of the draw layer is worth, which depends on how the producer that drew it blends. Both cases are a rate rather than a constant, and for the same reason.
ShapeVertex
One vertex of a filled custom shape.

Constants§

WAVE_MODES
How many wave_mode figures there are — MilkDrop’s own eight.

Functions§

build
Build the whole draw layer for this frame.
uv_to_world
uv (y down, 0..1) to the line renderer’s world space (y up, x scaled by the aspect).