vfpga-runner

vfpgaRunner · sources

A HOST module that runs a loaded `.vfpga` declarative effect spec — a "virtual FPGA bitstream" swapped into one reconfigurable card (inspired by, not a clone of, classic video-synth hardware). The module declares the full I/O SUPERSET it can wire — 4 video inputs (vin1..vin4), 4 CV inputs (cv1..cv4), 4 gate inputs (g1..g4), 2 video outputs (vout1 canonical / vout2 via read('outputTexture:vout2')), and an 8-slot generic param bank (p1..p8) — and a loaded VfpgaSpec (node.data.vfpga, picked from the "load preset…" menu) selects which subset is ACTIVE and what GL render-graph runs. The card is manifest-driven: it renders the full port superset as handles (inactive ones dimmed) and shows only the loaded spec's active CV inputs (each with a bipolar SCALE attenuverter + OFFSET + always-on scope), gate inputs (with an activity LED), and its mapped param knobs (p1..pN, labelled + ranged by the spec, MIDI-learnable). CV inputs are linear-scaled into named role uniforms; gate inputs raw-pass into synthetic gN_evt params that the factory hysteresis edge-detects (DOOM/backdraft convention) so a spec's shader can read a held level / rising-edge count. Specs are IN-REPO bundled TypeScript (no user-uploaded code in v1) collected by import.meta.glob; the render runs on the MAIN thread (#1811 — the render worker has no cross-thread input textures for vin1..vin4, its return protocol carries one picture per node so vout2 could not be served, and the card polls read('gateState') every frame). Preset change hot-swaps the GL pipeline. This foundation ships ONE VFPGA: smpte-bars, a pure SMPTE-style colour-bar generator (0 video in → 1 video out, one CV SHIFT role + BRIGHT/SAT params) — a deterministic always-on reference source for bringing up downstream effects.

vfpga-runner is a runtime that executes a loaded .vfpga declarative spec — a "virtual FPGA bitstream" — as a WebGL video effect. ONE registered host module declares the full I/O superset it can ever wire (4 video ins, 4 CV, 4 gates, 2 video outs, an 8-slot generic param bank); the loaded VfpgaSpec selects which subset is ACTIVE and what render-graph runs, the way a bitstream reconfigures an FPGA fabric. A fabric-described spec (a grid of typed tiles wired by a routing netlist) is place-and-routed into the GL pass pipeline; a spec may also carry a legacy hand-authored render graph as an escape hatch, and when a spec declares both, the fabric path wins at runtime (smpte-bars ships both — its fabric lowers byte-identically to its legacy effect — to dogfood place-and-route on the reference VFPGA). Changing the preset hot-swaps the effect: the old GL pipeline is disposed and a new one built, with the new spec's param-slot defaults seeded. Usage: pick a VFPGA from the card's "load preset…" menu (the bundled catalog ships smpte-bars as the default test-pattern generator plus glitch/datamosh-style effects: chroma-rot, databend-cvbs, framestore-howl, macroblock-mosh, scaler-glitch, sync-bender and tmds-sparkle). The card preview shows the REAL output of whatever VFPGA is loaded (a live blit of this node's own output FBO, not a frozen CPU snapshot); the "fabric" button toggles a read-only floorplan view (tile grid + lit routing nets). The card surfaces controls only for the loaded spec's active roles — a knob per mapped param slot, a SCALE attenuverter + OFFSET + always-on scope per active CV input, and an activity LED per active gate input — while the PatchPanel still renders the full superset of jacks (inactive ports dimmed). On the FACEPLATE the same surface is arranged as three bands - the VFPGA picker, the eight generic slot knobs, and a CV conditioning rack carrying each active CV role's SCALE attenuverter, OFFSET and live trace - with the output picture, a SCREEN on/off switch and the fabric floorplan view in the plate's own body. This module renders on the MAIN thread: it declares four video inputs the render worker cannot supply textures for, two video outputs the single-ImageBitmap return protocol cannot both carry, and a per-frame gate-state probe the worker proxy can only serve by materialising a main-thread fallback anyway.

Full guide: VFPGA runner guide The video-FPGA effect runner — the tile model, the catalog, and how to wire it.

the faceplate

vfpga-runnervout1videovout2videoaudiocvgatepitch
0 inputs · 2 outputs · 0 params

outputs

idcablewhat it does
vout1videoPrimary video output — the canonical surface texture. The loaded spec's vout1 FBO (the final pass writing 'output'); always present, and what downstream modules and OUTPUT sample.
RGB video stream
vout2videoSecondary video output. Exposed only when the loaded spec declares a vout2 FBO (read('outputTexture:vout2')); otherwise null/inactive. Lets a multi-output effect tap a second buffer.
RGB video stream

controls

controlwhat it does
Cv1 valSynthetic CV param for the cv1 jack (no knob). Carries the raw CV sample written by the cv1 input; read as the loaded spec's CV-role-1 modulation uniform after the card's SCALE attenuverter + OFFSET.
Cv2 valSynthetic CV param for the cv2 jack (no knob). Holds the raw cv2 sample, surfaced to the loaded spec's CV-role-2 uniform post SCALE + OFFSET.
Cv3 valSynthetic CV param for the cv3 jack (no knob). Holds the raw cv3 sample, read by the loaded spec's CV-role-3 uniform after SCALE + OFFSET.
Cv4 valSynthetic CV param for the cv4 jack (no knob). Holds the raw cv4 sample, read by the loaded spec's CV-role-4 uniform after SCALE + OFFSET.
G1 evtSynthetic gate param for the g1 jack (no knob). The factory hysteresis edge-detector turns this raw sample into the held-level and rising-edge-count uniforms the loaded spec's gate-role-1 reads.
G2 evtSynthetic gate param for the g2 jack (no knob). Edge-detected into the held-level and rising-edge-count uniforms consumed by the loaded spec's gate-role-2.
G3 evtSynthetic gate param for the g3 jack (no knob). Edge-detected into the held-level / rising-edge-count uniforms the loaded spec's gate-role-3 reads.
G4 evtSynthetic gate param for the g4 jack (no knob). Edge-detected into the held-level / rising-edge-count uniforms the loaded spec's gate-role-4 reads.
P1Generic param slot 1 (host 0..1). A loaded VFPGA maps and labels one of its params onto this slot; the card renders a knob in the spec's [min,max] range only when the loaded spec uses the slot. The mapped value drives the bound shader uniform.
P2Generic param slot 2. Surfaced as a labeled knob (in the spec's mapped range) only if the loaded VFPGA maps a param onto it; otherwise hidden. CV patched to the same uniform adds on top of this base.
P3Generic param slot 3. A labeled knob appears only when the loaded spec maps a param here; the host slot is generic 0..1, shown to the user in the spec's [min,max] range.
P4Generic param slot 4. Mapped + labeled by the loaded VFPGA when used; renders a knob in the spec's range, otherwise inactive.
P5Generic param slot 5. Labeled and ranged by whichever spec param the loaded VFPGA maps onto it; no knob when the slot is unused by the loaded spec.
P6Generic param slot 6. Surfaced as a knob (spec label + range) only when the loaded VFPGA uses the slot; the underlying host value is a 0..1 generic slot.
P7Generic param slot 7. Mapped + labeled per the loaded spec; renders a knob in the mapped range when active, otherwise dimmed/hidden.
P8Generic param slot 8 — the last of the p1..p8 bank. Labeled and ranged by the loaded VFPGA's mapped param when used; no knob otherwise.
Vfpga cv {n}Modulation rack - one strip per CV role the LOADED VFPGA declares, each carrying a SCALE attenuverter (-1..+1, so it inverts), an OFFSET (0..1), and an always-on trace of the value that actually reaches the shader uniform; then an activity lamp per active gate role. SCALE and OFFSET are applied to the raw cv1..cv4 sample before the spec's cvRole adds it onto its uniform, so they set how far and in which direction a patched cable swings that role. They live in node.data.cvInputs (never per-frame Y.Doc writes) and are the same values the legacy card's per-CV SCALE/OFFSET knobs write. The lamps read the factory's held gate state, the same read('gateState') seam the card polls. A spec that declares neither CV nor gate roles renders an empty rack.
Vfpga preset {n}VFPGA picker - the dropdown listing every bundled .vfpga bitstream by name (smpte-bars, chroma-rot, databend-cvbs, framestore-howl, macroblock-mosh, scaler-glitch, sync-bender, tmds-sparkle). Picking one writes node.data.vfpga and hot-swaps the running effect: the old GL pipeline is disposed, the new spec's passes are compiled, and its param-slot defaults are seeded into p1..p8 so the loaded program renders with its intended bend amounts immediately. It is the module's identity control - every other control here means something different depending on what this one says. On the legacy card the same action is the "load preset..." menu.

source

vfpga-runner.ts on GitHub.

Generated from packages/web/src/lib/{audio,video}/module-registry.ts · repo