Expand description
GLSL sources for every GPU effect (engine/gpu.rs compiles these).
Convention: one full-screen triangle vertex shader (VERT) plus a fragment shader per effect built
from PRELUDE + the effect body. A per-effect body (everything below the divider near the
bottom of this file) is a complete shader: it defines its own void main(), samples tex and mixes
its result back through the mask itself — see “Rules every body below follows”.
The vec4 effect(vec4 src, vec2 uv) + MAIN convention is used only where the caller supplies the
body: EffectKind::Shader (via user_shader) and gpu.rs’s COPY_BODY / MATTE_BODY. MAIN
samples tex, calls effect and applies the mask, so those bodies never write out_color.
fragment() does the assembly for both cases.
Uniforms available to every effect:
sampler2D tex the layer being processed (straight alpha, top-down)
vec2 u_res layer size in pixels
float u_time clip-local seconds
float u_scale canvas px per project px (pixel-sized params must multiply by this)
float p0..p7 the effect parameters in EffectKind::params() order
sampler2D u_mask mask coverage (1 = apply); u_has_mask is 0 when there is none
Fragment output is out_color (straight alpha).
Textures are uploaded top-down and the vertex shader flips the clip-space Y instead, so uv.y = 0
is the top of the image everywhere — in the sampler, in glReadPixels output and in egui.
Constants§
- BLEND
- Blend modes as a GLSL function (
vec3 blend(int mode, vec3 s, vec3 d)) mirroring engine::blend. The int isBlendMode::ALL’s index — seeblend_indexin engine/gpu.rs. - BLOB_
TRACK 🔒 - Overlay for the colour tracker: tints everything within
Toleranceof the target and draws a crosshair at the centroid. - BLUR 🔒
- 24-tap Vogel disc, Gaussian-weighted; radius
p0project px. - CHROMA_
KEY 🔒 - Chroma key: distance in the Cb/Cr plane to the key colour, with spill removal, matte erode/dilate (p7 project px, + shrinks) and a show-mask switch (p5).
- COLOR 🔒
- Saturation + hue matrix (same feColorMatrix pair as the CPU path), then brightness/contrast/gamma.
- COLOR_
REPLACE 🔒 - Replace one colour with another: RGB distance to the source colour, faded out over
Tolerance .. Tolerance + Softness(distance normalised so 1.0 is black-to-white). - COMPOSITE
- Composite/transform shader: samples a layer through an inverse 3x3 (perspective-capable) matrix with
the chosen
Scaler(0 = nearest, 1 = bilinear, 2 = bicubic Catmull-Rom) and blends it onto the canvas. Appended toPRELUDE+BLEND.u_invmaps canvas pixels (y down) to layer uv. - CROP 🔒
- Left/Right/Top/Bottom fractions cut away (alpha 0) with a
p4feather. - CURVES 🔒
- Twelve knots (master, R, G, B) driving a monotone cubic through (0,0) (.25,a) (.5,b) (.75,c) (1,1).
Fritsch-Carlson tangents keep the spline monotone, so a curve never folds back on itself.
Declares p8..p11 itself:
PRELUDEonly carries p0..p7. - EDGE_
GLOW 🔒 - Sobel on luma with the tap spacing set by
Width(p1) - a wider kernel is the cheap stand-in for dilating the edge - then a coloured glow, optionally over the source. - FLIP 🔒
- p0 = horizontal, p1 = vertical (>= 0.5 = on).
- GRAYSCALE 🔒
- HUE_
SHIFT 🔒 - Hue rotate (p0 degrees), saturation multiply (p1) and lightness offset (p2) in HSL.
- INVERT 🔒
- JPEG_
COMPRESS 🔒 - JPEG-ish: the block DC (4 taps) is quantised coarsely, the AC residual more coarsely still, and the
chroma optionally read from a 2x2 grid (4:2:0). This is an approximation - there is no DCT here,
but the visible artefacts (blocking, colour smear, banding) track
Qualitythe same way. - LEVELS 🔒
- In black/white, gamma, out black/white (same convention as Color’s gamma: v^(1/g)).
- MAIN
- Entry point appended after a
vec4 effect(vec4 src, vec2 uv)body: sample, runeffect, mask. Used byuser_shader(EffectKind::Shader) and gpu.rs’s copy/matte programs only — the built-in bodies below writeout_colorthemselves. - MASK
- Mask rasteriser (rect / ellipse / polygon / path with feather, expand, invert, rotation).
Appended to
PRELUDE; everything is in canvas pixels, relative to the layer centre. Writes coverage to every channel so it reads as.r(a matte) or as alpha. - MOTION_
BLUR 🔒 - Shutter-window average of the frames gpu.rs supplies.
- PIXELATE 🔒
- Snap to a
p0-project-px block grid and sample its centre. - PRELUDE
- Shared header: version, precision, varyings, the uniform block and helpers (rgb<->hsl, luma, hash noise, clamped sampling, mask application).
- REC_DOT 🔒
- Blinking record dot in a corner (p2: 0 = top-left, 1 = top-right, 2 = bottom-left, 3 = bottom-right) plus an optional HH:MM:SS timecode drawn as seven-segment quads from the clip-local time.
- SHARPEN 🔒
- Unsharp mask against a 3x3 box at
p1project px spacing. - THRESHOLD 🔒
- Hard/soft threshold on luma, or per channel when p2 >= 0.5.
- TINT 🔒
- Mix towards (p0,p1,p2) 0..255 by p3.
- VERT
- Full-screen triangle; no vertex buffer needed (gl_VertexID based).
- VHS 🔒
- One-pass VHS: per-line tracking jitter, chroma bleed to the right of an edge, luma noise, scanlines, sharpening ringing, a head-switching band at the bottom and tape-wear dropouts. Cheap approximations of what ntsc-rs models properly - no line-rate filtering, no real comb filter.
- VIGNETTE 🔒
- Darken outside
p0(fraction of the half diagonal) withp1softness byp2.
Functions§
- body
- Body for each
EffectKindthat runs on the GPU.None= geometric or CPU-only. - fragment
- The complete fragment source for one effect, or None when it has no GPU body.
- user_
shader - Wrap a user shader body (
EffectKind::Shader) so it sees the same prelude and knobsu1..u8. The body must definevec4 effect(vec4 src, vec2 uv)(seemodel::DEFAULT_SHADER).