colour of magic
colourofmagic · effectsCOLOUR OF MAGIC — a multi-colorspace video PROCESSOR. One video IN runs through FIVE parallel colorspace blocks — RGB, YDbDr (the SECAM luma+chroma broadcast space), HSV-or-HSL, YIQ (the NTSC composite space, its orange↔cyan flesh-tone I axis + green↔magenta Q axis), and YCbCr BT.601 STUDIO-SWING (the broadcast-legal 16–235 / 16–240 window whose ~1.16× decode expansion CRUSHES super-black/white like a proc-amp) — each block encoding the picture into that space, adjusting each component, then decoding back to RGB. Every block has, per channel: a BIAS knob (additive offset, identity at 0) that also sums CV patched into its cv input; a MONO OVERRIDE input that REPLACES that channel with an incoming grayscale/video stream (bias still adds on top, so a patched key can still be offset); and an OVER/CLAMP toggle — CLAMP clips out-of-range to 0..1 (a legal clip) while OVER wraps it around via fract() (the LZX chroma-wrap look where over-driven values fold back through the spectrum). Bipolar chroma rides a 0.5 pedestal (YDbDr Db/Dr, YIQ I/Q) or the authentic 128/255 = 0.502 pedestal (studio-swing Cb/Cr); HUE always wraps regardless of its toggle (which is advisory). The third block switches HSV↔HSL. TWENTY-TWO outputs run in parallel: pass (the untouched source); rgb / ydbdr / hsvhsl / yiq / ycc (each block colorized); and per-block grayscale channel taps — r / g / b / luma (RGB), ydb_y/db/dr (YDbDr), hsv_h/s/v (HSV·HSL), yiq_y/i/q (YIQ, its mono I tap a ready-made warmth/skin key), ycc_y/cb/cr (studio-swing). The RGB block also has a palette REPLACE mode: three colour-picker swatches remap the adjusted R/G/B channels to chosen output colours (a duotone/tritone recolour) before the rgb out — picking a swatch auto-enables REPLACE and the swatches default to a non-identity teal/orange/violet so it recolours immediately. Only the outputs you PATCH downstream (plus the one you PREVIEW) are rendered each frame, so the many taps stay cheap. With nothing patched all outputs are opaque black. All colorspace math is a 1:1 mirror of the pure, unit-tested $lib/video/colourofmagic-colorspace core. The card has a live preview (with a 22-way output selector), the five block columns of knobs + OVER/CLAMP pills, the HSV/HSL toggle, and the palette REPLACE swatches; all CV + mono-override jacks + the 22 outputs live in the sectioned yellow drill-down PATCH PANEL (IN / RGB / YDbDr / HSV-HSL / YIQ / YCbCr / OUT, no raw side jacks).
the faceplate
inputs
| id | cable | what it does |
|---|---|---|
in | video | The source picture. All three blocks read it in parallel. With nothing patched here every output is opaque black. RGB video stream |
rgb_r_cv | cv | CV that modulates the RGB block's r bias (linear -1..1 additive offset on the red channel). control voltage (CV); modulates bias_r (additive offset — ±1 CV sweeps the full range, centered on the knob) |
rgb_r_in | mono-video | Mono override for the RGB red channel: when patched, its value REPLACES red before the bias/CV offset and OVER/CLAMP. Accepts a keys/mono-video stream (a full video/image lands legally and is read as its red). mono video stream; also accepts: mono still image (keys), RGB still image, RGB video stream |
rgb_g_cv | cv | CV that modulates the RGB block's g bias (linear -1..1 offset on green). control voltage (CV); modulates bias_g (additive offset — ±1 CV sweeps the full range, centered on the knob) |
rgb_g_in | mono-video | Mono override for the RGB green channel (replaces green pre-offset). Accepts keys/mono-video/video/image. mono video stream; also accepts: mono still image (keys), RGB still image, RGB video stream |
rgb_b_cv | cv | CV that modulates the RGB block's b bias (linear -1..1 offset on blue). control voltage (CV); modulates bias_b (additive offset — ±1 CV sweeps the full range, centered on the knob) |
rgb_b_in | mono-video | Mono override for the RGB blue channel (replaces blue pre-offset). Accepts keys/mono-video/video/image. mono video stream; also accepts: mono still image (keys), RGB still image, RGB video stream |
ydb_y_cv | cv | CV that modulates the YDbDr block's y (luma) bias (linear -1..1 offset in the packed 0..1 space). control voltage (CV); modulates bias_y (additive offset — ±1 CV sweeps the full range, centered on the knob) |
ydb_y_in | mono-video | Mono override for the YDbDr luma (Y) channel, packed 0..1 (replaces Y pre-offset). mono video stream; also accepts: mono still image (keys), RGB still image, RGB video stream |
ydb_db_cv | cv | CV that modulates the YDbDr Db (blue-yellow chroma) bias (linear -1..1 in packed space). control voltage (CV); modulates bias_db (additive offset — ±1 CV sweeps the full range, centered on the knob) |
ydb_db_in | mono-video | Mono override for the YDbDr Db chroma channel, packed 0..1 (0.5 = neutral). mono video stream; also accepts: mono still image (keys), RGB still image, RGB video stream |
ydb_dr_cv | cv | CV that modulates the YDbDr Dr (red-cyan chroma) bias (linear -1..1 in packed space). control voltage (CV); modulates bias_dr (additive offset — ±1 CV sweeps the full range, centered on the knob) |
ydb_dr_in | mono-video | Mono override for the YDbDr Dr chroma channel, packed 0..1 (0.5 = neutral). mono video stream; also accepts: mono still image (keys), RGB still image, RGB video stream |
hsv_h_cv | cv | CV that modulates the HSV/HSL block's hue bias (linear -180..180 degrees; hue always wraps). control voltage (CV); modulates bias_h (additive offset — ±1 CV sweeps the full range, centered on the knob) |
hsv_h_in | mono-video | Mono override for HUE (0..1, wraps): replaces the hue angle before the degree bias. mono video stream; also accepts: mono still image (keys), RGB still image, RGB video stream |
hsv_s_cv | cv | CV that modulates the HSV/HSL block's saturation bias (linear -1..1 offset). control voltage (CV); modulates bias_s (additive offset — ±1 CV sweeps the full range, centered on the knob) |
hsv_s_in | mono-video | Mono override for SATURATION (0..1): replaces saturation pre-offset. mono video stream; also accepts: mono still image (keys), RGB still image, RGB video stream |
hsv_v_cv | cv | CV that modulates the HSV/HSL block's value/lightness bias (linear -1..1 offset). control voltage (CV); modulates bias_v (additive offset — ±1 CV sweeps the full range, centered on the knob) |
hsv_v_in | mono-video | Mono override for VALUE (HSV) / LIGHTNESS (HSL), 0..1: replaces it pre-offset. mono video stream; also accepts: mono still image (keys), RGB still image, RGB video stream |
yiq_y_cv | cv | CV that modulates the YIQ block's Y (luma) bias (linear -1..1 offset in packed 0..1 space). control voltage (CV); modulates bias_yiq_y (additive offset — ±1 CV sweeps the full range, centered on the knob) |
yiq_y_in | mono-video | Mono override for the YIQ luma (Y) channel, packed 0..1 (replaces Y pre-offset). mono video stream; also accepts: mono still image (keys), RGB still image, RGB video stream |
yiq_i_cv | cv | CV that modulates the YIQ I (orange↔cyan flesh-tone) bias (linear -1..1 in packed space). control voltage (CV); modulates bias_yiq_i (additive offset — ±1 CV sweeps the full range, centered on the knob) |
yiq_i_in | mono-video | Mono override for the YIQ I chroma channel, packed 0..1 (0.5 = neutral; a warmth/skin key). mono video stream; also accepts: mono still image (keys), RGB still image, RGB video stream |
yiq_q_cv | cv | CV that modulates the YIQ Q (green↔magenta) bias (linear -1..1 in packed space). control voltage (CV); modulates bias_yiq_q (additive offset — ±1 CV sweeps the full range, centered on the knob) |
yiq_q_in | mono-video | Mono override for the YIQ Q chroma channel, packed 0..1 (0.5 = neutral). mono video stream; also accepts: mono still image (keys), RGB still image, RGB video stream |
ycc_y_cv | cv | CV that modulates the studio-swing Y' (studio luma) bias (linear -1..1; decode amplifies it ~1.16×). control voltage (CV); modulates bias_ycc_y (additive offset — ±1 CV sweeps the full range, centered on the knob) |
ycc_y_in | mono-video | Mono override for the studio-swing luma (Y') channel, encoded 0..1 (blacks ~0.063, whites ~0.922). mono video stream; also accepts: mono still image (keys), RGB still image, RGB video stream |
ycc_cb_cv | cv | CV that modulates the studio-swing Cb (blue-yellow legal chroma) bias (linear -1..1). control voltage (CV); modulates bias_ycc_cb (additive offset — ±1 CV sweeps the full range, centered on the knob) |
ycc_cb_in | mono-video | Mono override for the studio-swing Cb chroma channel, encoded 0..1 (0.502 = neutral). mono video stream; also accepts: mono still image (keys), RGB still image, RGB video stream |
ycc_cr_cv | cv | CV that modulates the studio-swing Cr (red-cyan legal chroma) bias (linear -1..1). control voltage (CV); modulates bias_ycc_cr (additive offset — ±1 CV sweeps the full range, centered on the knob) |
ycc_cr_in | mono-video | Mono override for the studio-swing Cr chroma channel, encoded 0..1 (0.502 = neutral). mono video stream; also accepts: mono still image (keys), RGB still image, RGB video stream |
outputs
| id | cable | what it does |
|---|---|---|
pass | video | The source video, UNMODIFIED — independent of all three blocks. Opaque black when IN is unpatched. RGB video stream |
rgb | video | The RGB block's colorized output: per-channel adjusted red/green/blue, then the optional palette REPLACE remap. RGB video stream |
ydbdr | video | The YDbDr block's colorized output: adjusted Y/Db/Dr decoded back to RGB (the SECAM look). RGB video stream |
hsvhsl | video | The HSV or HSL block's colorized output (per the HSL toggle): adjusted hue/sat/value(lightness) decoded to RGB. RGB video stream |
r | mono-video | Mono-video: the R channel of the ADJUSTED RGB block as grayscale (before the palette remap). mono video stream |
g | mono-video | Mono-video: the G channel of the ADJUSTED RGB block as grayscale. mono video stream |
b | mono-video | Mono-video: the B channel of the ADJUSTED RGB block as grayscale. mono video stream |
luma | mono-video | Mono-video: Rec.601 luma (0.299R+0.587G+0.114B) of the ADJUSTED RGB block, grayscale. mono video stream |
ydb_y | mono-video | Mono-video: the adjusted YDbDr luma (Y) channel as grayscale (packed 0..1). mono video stream |
ydb_db | mono-video | Mono-video: the adjusted YDbDr Db (blue-yellow) chroma as grayscale (0.5 = neutral). mono video stream |
ydb_dr | mono-video | Mono-video: the adjusted YDbDr Dr (red-cyan) chroma as grayscale (0.5 = neutral). mono video stream |
hsv_h | mono-video | Mono-video: the adjusted HUE as grayscale (0..1, circular — a hard black↔white seam at 0≡1 is correct, not a defect). mono video stream |
hsv_s | mono-video | Mono-video: the adjusted SATURATION as grayscale (0..1). mono video stream |
hsv_v | mono-video | Mono-video: the adjusted VALUE (HSV) / LIGHTNESS (HSL) as grayscale (0..1). mono video stream |
yiq | video | The YIQ block's colorized output: adjusted Y/I/Q decoded back to RGB (the NTSC composite look). RGB video stream |
yiq_y | mono-video | Mono-video: the adjusted YIQ luma (Y) channel as grayscale (same Rec.601 luma as `luma`). mono video stream |
yiq_i | mono-video | Mono-video: the adjusted YIQ I (orange↔cyan flesh-tone) chroma as grayscale — a ready-made warmth/skin key (0.5 = neutral). mono video stream |
yiq_q | mono-video | Mono-video: the adjusted YIQ Q (green↔magenta) chroma as grayscale (0.5 = neutral). mono video stream |
ycc | video | The studio-swing block's colorized output: adjusted Y'/Cb/Cr expanded + decoded to RGB (the broadcast-legal crush look). RGB video stream |
ycc_y | mono-video | Mono-video: the adjusted studio-swing luma (Y') as grayscale (studio range — blacks ~0.063, whites ~0.922). mono video stream |
ycc_cb | mono-video | Mono-video: the adjusted studio-swing Cb (blue-yellow legal chroma) as grayscale (0.502 = neutral). mono video stream |
ycc_cr | mono-video | Mono-video: the adjusted studio-swing Cr (red-cyan legal chroma) as grayscale (0.502 = neutral). mono video stream |
params
| id | label | range | default | curve |
|---|---|---|---|---|
bias_r | r | -1..1 | — | linear |
bias_g | g | -1..1 | — | linear |
bias_b | b | -1..1 | — | linear |
bias_y | y | -1..1 | — | linear |
bias_db | db | -1..1 | — | linear |
bias_dr | dr | -1..1 | — | linear |
bias_h | h | -180..180deg | — | linear |
bias_s | s | -1..1 | — | linear |
bias_v | v | -1..1 | — | linear |
bias_yiq_y | y | -1..1 | — | linear |
bias_yiq_i | i | -1..1 | — | linear |
bias_yiq_q | q | -1..1 | — | linear |
bias_ycc_y | y | -1..1 | — | linear |
bias_ycc_cb | cb | -1..1 | — | linear |
bias_ycc_cr | cr | -1..1 | — | linear |
over_r | r wrap | 0..1 | — | discrete |
over_g | g wrap | 0..1 | — | discrete |
over_b | b wrap | 0..1 | — | discrete |
over_y | y wrap | 0..1 | — | discrete |
over_db | db wrap | 0..1 | — | discrete |
over_dr | dr wrap | 0..1 | — | discrete |
over_s | s wrap | 0..1 | — | discrete |
over_v | v wrap | 0..1 | — | discrete |
over_h | h wrap | 0..1 | — | discrete |
over_yiq_y | y wrap | 0..1 | — | discrete |
over_yiq_i | i wrap | 0..1 | — | discrete |
over_yiq_q | q wrap | 0..1 | — | discrete |
over_ycc_y | y wrap | 0..1 | — | discrete |
over_ycc_cb | cb wrap | 0..1 | — | discrete |
over_ycc_cr | cr wrap | 0..1 | — | discrete |
mode_hsl | hsl | 0..1 | — | discrete |
replace | replace | 0..1 | — | discrete |
pal_r | r | 0..0 | — | discrete |
pal_g | g | 0..0 | — | discrete |
pal_b | b | 0..0 | — | discrete |
preview | preview | 0..21 | — | discrete |
freeze | freeze | 0..1 | — | discrete |
controls
| control | what it does |
|---|---|
| b | b: additive offset on the RGB blue channel, -1 to 1 (default 0). Sums with rgb_b_cv. |
| db | db: additive offset on the YDbDr Db (blue-yellow) chroma, -1 to 1 (default 0), around the 0.5 pedestal. Sums with ydb_db_cv. |
| dr | dr: additive offset on the YDbDr Dr (red-cyan) chroma, -1 to 1 (default 0), around the 0.5 pedestal. Sums with ydb_dr_cv. |
| g | g: additive offset on the RGB green channel, -1 to 1 (default 0). Sums with rgb_g_cv. |
| h | h: hue rotation for the HSV/HSL block, -180 to 180 degrees (default 0). Hue always wraps. Sums with hsv_h_cv. |
| r | r: additive offset on the RGB red channel, -1 to 1 (default 0 = no change). Sums with the rgb_r_cv input. |
| s | s: additive offset on saturation, -1 to 1 (default 0). Sums with hsv_s_cv. |
| v | v: additive offset on value (HSV) or lightness (HSL), -1 to 1 (default 0). Sums with hsv_v_cv. |
| y | y: additive offset on the YDbDr luma channel (packed 0..1 space), -1 to 1 (default 0). Sums with ydb_y_cv. |
| cb | cb: additive offset on the studio-swing Cb (blue-yellow legal chroma), -1 to 1 (default 0), around the 0.502 pedestal. Sums with ycc_cb_cv. |
| cr | cr: additive offset on the studio-swing Cr (red-cyan legal chroma), -1 to 1 (default 0), around the 0.502 pedestal. Sums with ycc_cr_cv. |
| y | y: additive offset on the studio-swing luma (Y'), -1 to 1 (default 0). Decode expands studio→full range, so the offset is AMPLIFIED ~1.16× (the broadcast crush). Sums with ycc_y_cv. |
| i | i: additive offset on the YIQ I (orange↔cyan flesh-tone) chroma, -1 to 1 (default 0), around the 0.5 pedestal — one nudge is a whole teal-&-orange grade. Sums with yiq_i_cv. |
| q | q: additive offset on the YIQ Q (green↔magenta) chroma, -1 to 1 (default 0), around the 0.5 pedestal. Sums with yiq_q_cv. |
| y | y: additive offset on the YIQ luma channel (packed 0..1 space), -1 to 1 (default 0). Sums with yiq_y_cv. |
| freeze | freeze: hidden determinism toggle — at 1 the renderer holds its last rendered frame (no redraw) for stable VRT capture. Default 0; no card control. |
| hsl | hsl: selects the third block's colorspace — HSV (0, default) or HSL (1). Affects the hsvhsl output + the v channel's meaning (value vs lightness). |
| b wrap | b wrap: overflow mode for the RGB blue channel (CLAMP default / WRAP). |
| db wrap | db wrap: overflow mode for the YDbDr Db chroma (CLAMP default / WRAP). |
| dr wrap | dr wrap: overflow mode for the YDbDr Dr chroma (CLAMP default / WRAP). |
| g wrap | g wrap: overflow mode for the RGB green channel (CLAMP default / WRAP). |
| h wrap | h wrap: ADVISORY only — hue ALWAYS wraps regardless of this toggle. Declared for UI symmetry with the other channels; disabled on the card. |
| r wrap | r wrap: overflow for the RGB red channel — CLAMP (0, default) clips out-of-range to 0..1; WRAP (1) folds it around via fract(). |
| s wrap | s wrap: overflow mode for saturation (CLAMP default / WRAP). |
| v wrap | v wrap: overflow mode for value/lightness (CLAMP default / WRAP). |
| y wrap | y wrap: overflow mode for the YDbDr luma channel (CLAMP default / WRAP). |
| cb wrap | cb wrap: overflow mode for the studio-swing Cb chroma (CLAMP default / WRAP — the illegal-chroma fold). |
| cr wrap | cr wrap: overflow mode for the studio-swing Cr chroma (CLAMP default / WRAP — the illegal-chroma fold). |
| y wrap | y wrap: overflow mode for the studio-swing luma (CLAMP clips at the legal boundary — a legalizer; WRAP folds super-white through black). |
| i wrap | i wrap: overflow mode for the YIQ I chroma (CLAMP default / WRAP — WRAP on the narrow-band chroma is the NTSC chroma-crawl fold). |
| q wrap | q wrap: overflow mode for the YIQ Q chroma (CLAMP default / WRAP). |
| y wrap | y wrap: overflow mode for the YIQ luma channel (CLAMP default / WRAP). |
| b | pal b: the palette colour the RGB blue channel maps to under REPLACE (packed 0xRRGGBB, default violet). Set via the card's colour picker. |
| g | pal g: the palette colour the RGB green channel maps to under REPLACE (packed 0xRRGGBB, default teal). Set via the card's colour picker. |
| r | pal r: the palette colour the RGB red channel maps to under REPLACE (packed 0xRRGGBB, default orange). Set via the card's colour picker (which auto-enables REPLACE). |
| preview | preview: which of the 22 outputs the on-card preview canvas shows (discrete 0..21: 0 pass, 1 rgb, 2 ydbdr, 3 hsvhsl, 4 r, 5 g, 6 b, 7 luma, 8 ydb_y, 9 ydb_db, 10 ydb_dr, 11 hsv_h, 12 hsv_s, 13 hsv_v, 14 yiq, 15 yiq_y, 16 yiq_i, 17 yiq_q, 18 ycc, 19 ycc_y, 20 ycc_cb, 21 ycc_cr). Default 1 (rgb). The previewed output is always rendered even when unpatched; other outputs render only when patched downstream. |
| replace | replace: turns the RGB palette REPLACE mode on (1) or off (0, default). When on, the adjusted R/G/B channels are recomposed from the three picked palette colours (duotone/tritone). Picking any swatch auto-enables it, and the swatches default to a non-identity teal/orange/violet, so it visibly recolours the rgb out as soon as it is on. |
source
colourofmagic.ts on GitHub.