cellshade
cellshade · effectsReal cel-shader (toon) video PROCESSOR — the canonical live-video cel pipeline (Winnemöller's Real-Time Video Abstraction) as a 4-pass chain. Takes a video input and emits a cel-shaded version: (1) an edge-preserving SEPARABLE BILATERAL smoothing pass (SMOOTH, 0..1, default 0.35 — 0 is a true bypass: the passes are skipped entirely) flattens low-contrast texture/noise into the large flat regions that read as hand-painted while keeping strong contours crisp; (2) a SOFT LUMINANCE QUANTIZATION pass collapses the smoothed image's Rec. 601 luma into N flat tonal bands — BANDS is a 5-step DISCRETE knob mapping to {2, 3, 4 (default), 6, 8} bands (the param id stays the legacy `bits`, same 0..4 index range, so saved patches + CV cables load with zero migration) — with a smoothstep transition whose half-width SOFT (0..1, default 0.25) widens from hard-edged bands to a near-continuous ramp; reconstruction is the additive luma shift out = clamp(rgb + (Yq − Y)) (YCbCr Y-replacement), so CHROMA IS NEVER QUANTIZED — hue and saturation ride through and each band is a flat tonal step of consistent colour (a yellow stays yellow, a skin tone stays warm); (3) a Sobel INK pass (the exact EDGES algorithm — same Rec. 601 luma, normalisation, THRESHOLD gate and THICKNESS dilation — measured on the SMOOTHED image so sensor noise never inks) composites the salient contours as dark outline strokes scaled by INK (0..1, default 1: 0 = no lines, 1 = solid black). STATELESS per frame — the look tracks the live source with no feedback. THRESHOLD (0..1, default 0.2) gates which contours get inked; THICKNESS (1..8 px, default 2) dilates the strokes wider. All six params have matching CV inputs (port id == param id; BANDS uses a discrete cvScale so CV snaps to the 5 steps). IN takes RGB; OUT is video — patch a source (CAMERA / VIDEOBOX / SHAPES / a generator) → IN, OUT → OUTPUT or a video mixer; drop BANDS + raise INK for bold comic cels, raise SMOOTH for painterly abstraction, use SOFT to trade crisp band edges against shimmer-free gradients on live video. (The old 8/16-bit per-channel RGB retro posterize modes were dropped in the rebuild — that look is posterization, not cel, and belongs to the POSTERBOX module.)
the faceplate
inputs
| id | cable | what it does |
|---|---|---|
in | video | The RGB video source to cel-shade. It is smoothed, luminance-banded and inked; with no input the output is solid black. RGB video stream |
threshold | cv | CV input that modulates Thresh, sweeping the ink gate linearly over its full 0..1 range — higher CV inks fewer, stronger contours. control voltage (CV); modulates threshold (additive offset — ±1 CV sweeps the full range, centered on the knob) |
thickness | cv | CV input that modulates Thick, sweeping the ink stroke width linearly over its 1..max px range — higher CV makes the outlines wider. control voltage (CV); modulates thickness (additive offset — ±1 CV sweeps the full range, centered on the knob) |
bits | cv | CV input that modulates Bands using a discrete cvScale, so the CV snaps to the 5 band-count steps (2/3/4/6/8 luminance bands) rather than sweeping continuously. control voltage (CV); modulates bits (integer buckets — CV selects a discrete step) |
softness | cv | CV input that modulates Soft, sweeping the band-transition width linearly over its full 0..1 range — higher CV melts the band edges toward a continuous ramp. control voltage (CV); modulates softness (additive offset — ±1 CV sweeps the full range, centered on the knob) |
smooth | cv | CV input that modulates Smooth, sweeping the bilateral abstraction linearly over its full 0..1 range — higher CV flattens more texture into painted regions. control voltage (CV); modulates smooth (additive offset — ±1 CV sweeps the full range, centered on the knob) |
ink | cv | CV input that modulates Ink, sweeping the outline darkness linearly over its full 0..1 range — 0 removes the lines, 1 draws them solid black. control voltage (CV); modulates ink (additive offset — ±1 CV sweeps the full range, centered on the knob) |
outputs
| id | cable | what it does |
|---|---|---|
out | video | The cel-shaded video frame: flat soft luminance bands with the source's hue preserved, plus dark ink strokes over the detected contours. RGB video stream |
params
| id | label | range | default | curve |
|---|---|---|---|---|
threshold | Thresh | 0..1 | — | linear |
thickness | Thick | 1..?px | — | linear |
bits | Bands | 0..? | — | discrete |
softness | Soft | 0..1 | — | linear |
smooth | Smooth | 0..1 | — | linear |
ink | Ink | 0..1 | — | linear |
controls
| control | what it does |
|---|---|
| Bands | Bands — a 5-step discrete control selecting the luminance band count: 2, 3, 4 (default), 6 or 8 flat tonal bands. Fewer bands is a bolder, more graphic cel; more bands keeps subtler tonal detail. Only brightness is banded — hue and saturation always pass through. (The param id is the legacy `bits` so old patches load unchanged.) |
| Ink | Ink — outline darkness (0..1, default 1). Scales the black contour composite: 0 draws no lines at all, 1 inks them solid black, in between dims them proportionally. |
| Smooth | Smooth — the edge-preserving bilateral abstraction (0..1, default 0.35). 0 is a true bypass (the smoothing passes are skipped entirely); raising it flattens texture and noise into larger painted regions while strong contours stay put. |
| Soft | Soft — the band-transition half-width (0..1, default 0.25). 0 is hard-edged bands (crisp but can shimmer on live video); raising it widens the smoothstep between bands until, near 1, the transfer is almost continuous. |
| Thick | Thick — ink stroke width in pixels (1..max, default 2, shared with EDGES). It dilates the edge mask, so higher values make the outlines wider; 1 is a thin single-pixel line. |
| Thresh | Thresh — the ink gate (normalized Sobel gradient magnitude, 0..1, default 0.2, shared with EDGES, measured on the smoothed image). Lower inks more/weaker contours; higher inks only the strongest edges. |
source
cellshade.ts on GitHub.