Expand description
Custom-wave (wavecode_N) pass.
The MD2 wavecode_N block defines up to four user-driven waves that
run their own per_frame_init / per_frame / per_point equations.
Per frame the engine evaluates each enabled wave’s per-point loop on
the CPU, producing a stream of (x, y, r, g, b, a) 6-tuples; this
module uploads that stream into a dynamic vertex buffer and dispatches
either a line-list or triangle-list draw.
Why CPU-emit vs. GPU-derive: each preset’s per-point equations can
reference arbitrary user state (q* channels, the audio buffer,
whatever a preset author thought up) — running them on the GPU would
require porting the evaluator. The line/dot geometry is tiny enough
that uploading expanded vertices each frame is the cheaper path.
Pipeline matrix:
- Topology is chosen at submit time:
LineStripforb_use_dots = 0(one strip per wave; segments break at wave boundaries via per-wave draw calls),TriangleListforb_use_dots = 1(each point expands CPU-side into a small 2-tri quad). - Blend is alpha or additive, picked by
b_additive.
Dispatch slot: the renderer calls into this pass between the legacy
waveform pass and the blur pyramid, so custom waves feed back next
frame and contribute to GetBlur*. Same slot the historical
waveform pass uses.
Structs§
- Custom
Wave Batch - One dispatch unit: the slice of the vertex buffer that belongs to a
single
wavecode_Nblock, plus its blend/topology flags. The renderer reuses a single growable buffer across all waves and walks the batches to issue one draw call each. - Custom
Wave Renderer - Custom-wave GPU pass. Owns one growable vertex buffer + two
pipelines (lines and dots topology, alpha and additive blend = 4
combinations, indexed by
pipeline_index(dots, additive)). - Custom
Wave Vertex - One vertex of the custom-wave stream. The shader is pure passthrough
—
posis already clip-space[-1, 1],coloris the per-point RGBA afterr/g/b/acarried through the per-point loop.
Constants§
- MAX_
CUSTOM_ WAVE_ VERTICES - Maximum total custom-wave vertices we’ll buffer in a frame. Four waves × 512 samples × (2 lines = 6 verts/segment, dots = 6 verts/point) ≈ 12 288. Round up to 16 384 to leave headroom for the next-sprint custom-shape pass, which will reuse this buffer layout.
Functions§
- pipeline_
index 🔒 - point_
to_ dot_ quad - Expand one MD2 per-point output
(x, y, r, g, b, a)into a small screen-space quad (two triangles, six vertices). Used by the dots pipeline.radius_clipis the half-side in clip space — pick2.0 / heightfor a single-pixel-equivalent dot at default sizing. - preset_
xy_ to_ clip - Convert MD2 preset-space
(x, y)(origin top-left, range[0, 1]) into clip-space(x', y')(origin centre, range[-1, 1], Y-up). - segment_
to_ thick_ quad - Expand two consecutive per-point outputs into a thick-line segment
quad — six clip-space vertices forming a screen-space rectangle of
thickness_clipperpendicular to the segment direction. Mirrors theline_vertexshape used bywaveform_advanced.wgslforb_wave_thick, so MD2’s “thick custom-wave trail” looks identical to the thick-static-wave path.