Effects
MasterSelects has a modular GPU effect system built around registered effect modules, shared WGSL utilities, and a compositor pipeline that can run inline color ops without extra passes.
At A Glance
Section titled “At A Glance”- 37 blend modes are implemented in
src/shaders/composite.wgsl. - 96 GPU effects are registered in
src/effects/, including fullscreen fragment effects, compute effects, glyph effects, tracking effects, and specialized render effects. - The populated clip-effect categories are
color,blur,distort,stylize,keying,halftone,analog,pixel,glyph,geometry, andtracking. generate,time, andtransitionhave no registered clip-stack effects and are hidden from the add-effect UI. Timeline transitions are implemented separately insrc/transitions/because they own two clips, source handles, hold-frame policy, and export participants.
Registry And UI
Section titled “Registry And UI”The effect registry is built from category exports in src/effects/index.ts.
Fullscreen effect definitions provide:
id,name, andcategory- WGSL shader source
- fragment
entryPoint uniformSize- parameter definitions
packUniforms(...)- optional
passesandcustomControls
Parameter definitions may also declare a named group. The generic controls
render those groups as focused sections and keep quality parameters in their
own collapsible section.
Specialized render and compute effects use an explicit pipelineKind
discriminator. They
are registered for UI/project data, but are skipped by the fullscreen
fragment path. Compute definitions are dispatched by ComputeEffectRuntime;
specialized render definitions are rendered by their dedicated compositor
pass.
The production editor UI is src/components/panels/properties/EffectsTab.tsx.
src/effects/EffectControls.tsx is a generic fallback renderer.
The add-effect control opens a searchable, categorized catalog instead of a
plain dropdown. Visible tiles are rendered from the current user frame and use
a deterministic color/initials placeholder until their GPU result is ready.
For motion-adjustment clips, the production tab limits the picker to
Brightness, Contrast, Saturation, Invert, and Gaussian Blur.
Current Effect Categories
Section titled “Current Effect Categories”color(9): Brightness, Contrast, Saturation, Vibrance, Hue Shift, Temperature, Exposure, Levels, Invertblur(5): Box Blur, Gaussian Blur, Radial Blur, Zoom Blur, Motion Blurdistort(7): Pixelate, Kaleidoscope, Mirror, RGB Split, Twirl, Wave, Bulgestylize(12): Vignette, Grain, Sharpen, Posterize, Glow, Edge Detect, Scanlines, Threshold, Acuarela, Rom1, Voxel Relief, Pixel Particle Disintegratekeying(1): Chroma Keyhalftone(13): dithering, halftone, Riso, print, poster, stitch, and animated mosaic treatmentsanalog(10): glitch, crystal/glass, ribbon, CRT, prism, wave, hologram, compute Pixel Sort, and Analog Signal Labpixel(2): Blockify and Block Mosaicglyph(18): ASCII, word/number/symbol matrices, code, collage, brand, and stitch treatmentsgeometry(11): compute Voronoi, Quadtree, and Contour plus engraving, textile, outline, and brick treatmentstracking(8): subject, motion/HUD/CCTV, kinetic trace, rain, stardust, and hand-particle treatments
Looks And Live Catalog Previews
Section titled “Looks And Live Catalog Previews”A Look is a serializable named stack of effect IDs, enabled flags, and primitive
parameters. The dockable Looks panel ships with 14 curated starter Looks,
supports search and category filtering, applies a complete stack in one history
operation, and can save/delete user Looks. Custom Looks persist through the
Zustand store; GPU textures, ImageBitmaps, and other runtime handles remain in
the separate HMR-safe thumbnail runtime.
Effect and Look tiles use a single captured frame at the current playhead as a shared source. The runtime renders 256x144 offscreen targets, caches by effect or stack parameters plus source-frame ID, schedules at most one queued preview job per animation frame, and only renders tiles within the viewport. This works for both main-thread and worker-presenting render hosts. Animated entries run at up to 12 fps for two seconds only while hovered or focused, with at most one animated tile active globally.
Clicking or touching either the live thumbnail or the Look name applies the Look to the selected clip; the thumbnail is a keyboard-focusable button as well.
Glyph, Cell, And Compute Effects
Section titled “Glyph, Cell, And Compute Effects”Glyph effects share one exact cell-grid model, curated ASCII ramps, and a generated glyph atlas cached beside the effect runtime. The same grid contract drives rendering and artifact export, so the exported rows match the visible cell selection instead of approximating it independently.
ComputeEffectRuntime adds storage-texture compute passes to the normal
ping-pong effect stack. Pixel Sort uses bounded segments, Voronoi uses a
jump-flood sequence, Quadtree Zoom evaluates hierarchical block variance, and
Contour uses marching-squares cases with interpolated edge crossings. Compute
and fragment effects can be mixed in one clip stack and use the same preview,
worker, and export paths.
Analog Signal Lab
Section titled “Analog Signal Lab”Analog Signal Lab is a dedicated six-pass compute effect rather than a
screen-space RGB glitch. It encodes the source as a 13.5 MHz PAL composite
field, applies a complex-equivalent terrestrial channel, passes the recovered
signal through an optional VHS transport, measures horizontal sync and color
burst per line, decodes PAL, and resolves an optional CRT display stage.
The exposed modules cover signal strength, band-limited RF/impulse noise, co-channel interference, two-path delayed ghosts with carrier phase and drift, receiver tuning and sync/color lock, PAL simple/delay-line/comb decoder modes, VHS tracking/dropouts/time-base error/tape wear/chroma bleed/head switching and SP/LP/EP speed, plus CRT scanlines, phosphor mask, bloom, curvature, and field flicker. Noise is seeded and driven by timeline time, so preview and export are repeatable.
The realtime path models one 313-line PAL field with a 360x288 decoded working raster while retaining the 864-sample line timing. When the effect is attached to a video/image plane switched to 3D, the analog stack is evaluated into a per-layer texture before native scene projection. The disturbance therefore foreshortens, rotates, and scales with the plane instead of being applied to the flattened synthetic scene texture afterward. The same routing is used for nested 3D compositions.
Landmark Tracking Effects
Section titled “Landmark Tracking Effects”The Effects tab can lazily track hand, face, or pose landmarks for a selected
video clip with the official @mediapipe/tasks-vision package and Apache-2.0
Google model files. Models/WASM load only on demand, Cache Storage retains the
downloaded runtime data, VIDEO-mode inference is CPU-backed and bounded to 8
fps / 300 frames, and cancellation restores the previous valid result.
Durable project/timeline data stores only serializable summaries. Full samples are kept in the runtime and in a gzip sidecar cache that can be restored after a page reload. Tracking effects receive a bounded 64-point storage buffer; Kinetic Trace can additionally consume the existing optical-flow analysis metadata without introducing a second motion-analysis pipeline.
Split Compare
Section titled “Split Compare”The main preview has an optional GPU split-compare pass. It binds the untreated and effected textures, composites them at an adjustable divider, and exposes a draggable/keyboard-accessible overlay. The setting is runtime UI state and does not alter project media or the exported result.
Parameter Editing
Section titled “Parameter Editing”EffectsTab renders effect parameters directly from the registry.
- Number parameters use a slider plus
DraggableNumber. - Boolean parameters use a checkbox.
- Select parameters use a dropdown.
- Parameters marked
quality: trueare grouped in a collapsibleQualitysection. - Quality values can be dragged past the visible slider max in the editor.
- Parameters marked
animatable: falseare shown as static controls. - Numeric parameters supplied by catalog, compute, and glyph effect factories default to animatable unless the effect explicitly opts out. This keeps the stopwatch/keyframe behavior consistent for registry-provided controls.
The registered quality parameters are:
- Gaussian Blur:
samples - Motion Blur:
samples - Radial Blur:
samples - Zoom Blur:
samples - Glow:
rings,samplesPerRing - Voxel Relief:
maxSteps - Pixel Particle Disintegrate:
maxPreviewParticles,maxExportParticles,maxInstances
Right-click on a numeric control resets that parameter to its default.
The performanceMonitor service can also reset quality parameters to defaults when rendering becomes too slow.
Inline Effects
Section titled “Inline Effects”These effects are applied directly in the composite shader instead of running as separate effect passes:
- Brightness
- Contrast
- Saturation
- Invert
That keeps them zero-overhead relative to the full ping-pong effect chain.
Particle Render Effects
Section titled “Particle Render Effects”Pixel Particle Disintegrate is a particle-render clip effect. It samples
the live source texture into deterministic instanced quads and resolves a
straight-alpha texture back into the normal layer compositor. At progress 0
the source is already represented by particle cells at their origin positions;
progress moves, curls, and fades those cells rather than crossfading from a
normal full-frame video plane. Particle release is driven by a deterministic
gust field: coherent noise pockets, a wind-front delay, and the clip seed decide
which regions separate first, so the breakup starts in scattered islands and
then grows without relying on accumulated simulation state. Each particle
carries UVs from its original source cell, so moving particles keep their
assigned image patch instead of sampling from their new screen position. Preview
and export use explicit render/media time instead of wall-clock time.
This effect is terminal in the clip effect stack. Effects before it are pre-rendered
into the particle source texture; effects after it are ignored with a renderer
warning instead of being silently reordered. The Effects tab includes a Particle Out
preset button that adds the effect and creates progress keyframes near the end
of the selected clip.
The worker-GPU compositor also runs the dedicated particle pass for preview and export, using the frame stack’s preview/export particle-quality setting.
Timeline Transitions
Section titled “Timeline Transitions”The Transition Suite is timeline-native rather than a normal one-clip effect
stack. Transition definitions live in src/transitions/ as serializable
primitive recipes (opacity, generated solid, mask, procedural/pattern
mask, blend, transform, generated overlay, UV distortion
primitives, and transition-scoped registered effect primitives) and are
interpreted by shared preview/export transition layer assembly. Analog/glitch
transitions that can be represented honestly as existing primitives, such as
seeded deterministic block masks, transform-based CRT collapse, or
transition-scoped registered effects for RGB split, pixelation, and static
scanlines, stay on that same preview/export path. Procedural noise/block masks
carry their normalized seed through preview, export, and the compositor shader
ABI so repeated renders are stable while non-default seeds can produce
alternate reveal orders. Water Drop and Swirl use the same seed path with
per-participant compositor UV remapping and are grouped under the Stylize
transition family. Blur Dissolve
and Zoom Blur use the same assembly path to append temporary registered GPU
effects to the incoming and outgoing participant layers while preserving each
clip’s existing effect stack. Directional Blur and Whip Pan use the same
registered-effect path with motion-blur; the Motion Blur shader mirrors edge
samples for out-of-range UVs so fast horizontal transition blurs do not expose
transparent borders. Projector Flicker uses deterministic generated-solid
exposure pulses, Film Roll combines vertical transform overscan with
transition-scoped Motion Blur, and Vignette Bloom uses registered glow and
vignette effects on both transition participants. Light Sweep uses a
cached transparent generated overlay canvas with a screen-blended diagonal
highlight band, while Light Leak uses the same deterministic overlay
primitive for warm edge streaks and analog wash. Those overlay canvases are
generated per output size and cached by dimensions plus rounded overlay
parameters, so preview and export do not upscale a fixed thumbnail texture.
Chroma Leak, Lens Flare, and Film Burn use that same overlay/cache model
with deterministic generated color-split, flare-ghost, and burn-edge overlays.
They stay deterministic without bundled overlay video. Additive Dissolve and
Non-Additive Dissolve
use temporary transition blend windows on the incoming participant, so they
stay in the same layer assembly path instead of adding one-off shaders.
The current user-facing suite is grouped by family in the Transitions panel and
the transition-scoped Properties tab. It includes dissolve/dip, directional
wipe, iris/shape, push/slide, dedicated 2D rotate, whole-card 3D
flip/tumble/roll/spin, stylize, glitch, light, zoom, and pattern-mask
families. Family cards show their variant count in the Transitions panel; a
click expands the draggable leaf variants until the pointer leaves the panel,
while dragging a collapsed family card uses that family’s default variant. The
current 3D families opt eligible participants into scene-3d-panel rendering
so video frames, video elements, images, and text canvases can render as native
shared-scene textured planes with camera projection and depth; unsupported
source states fall back to the compositor transform path. Kaleidoscope is an exotic
pattern-lab transition by reusing transition-scoped registered effect
primitives rather than adding a one-off compositor path. Puzzle Push,
Magnetic Tiles, and Shatter Glass are visible multi-panel
transitions: the layer contract supports normalized sourceRect sampling,
and transition assembly clones transition participants into deterministic
staggered panels, center-magnetic tiles, or rectangular outgoing tile-shatter.
The default placement is virtual center: the edit point remains stable,
neither clip is moved, and missing source handles render as first/last-frame
hold fallback when the policy allows it. Compositor-driven transitions pass
typed transition metadata through existing compositor uniform padding slots, so
normal layers pay no extra bind-group cost when transitionRender is absent.
Effect Pipeline
Section titled “Effect Pipeline”Non-inline fullscreen effects are compiled from shared WGSL utilities plus the
effect shader itself. The pipeline creates one GPU render pipeline per
non-inline fullscreen effect and filters out disabled effects and audio-
effects during application.
Effects with uniformSize 0 use no uniform buffer.
Most effects use a 16-byte-aligned uniform block; a few multi-parameter effects use larger blocks.
Effects can opt into temporal feedback through usesFeedback. Feedback effects
sample their own previous output frame on binding 3 and the pipeline maintains
a per-effect-instance feedback texture. Acuarela and the frozen Rom1 snapshot
use this path to build a watery smoke trail from animated fractal UV offsets.
The worker software renderer mirrors standalone Acuarela/Rom1 feedback with a
per-target/effect software feedback cache for preview and export readback;
Voxel Relief uses the same binding to smooth a
raymarched block-heightfield between video frames and remains a complex
raymarch/feedback effect.
Voxel Relief raymarches a perspective camera pointed at the source plane. The source image is sampled as a grid of rectangular prisms, with luminance driving each prism height and dark gaps between cells instead of a second flat video layer behind the relief.
Limit to Video keeps the existing extended field as the default for backward compatibility. When enabled, the
raymarcher discards voxel cells outside the source rectangle and uses a finite source-sized floor, so orbit views show
only the actual video footprint instead of repeating its edge pixels around the subject.
Voxel Relief camera & orbit mode
Section titled “Voxel Relief camera & orbit mode”The effect’s virtual camera is fully parameterized: tilt, yaw (±180°, full
orbit), perspective (FOV), distance (dolly multiplier, 1 = classic framing),
centerX/centerY (focus point), roll, and lightFollow (light azimuth
rotates with yaw so the far side never falls fully into shadow). The raymarch
budget scales with camera distance and skips empty space above the relief, so
far zoom-outs stay intact. Params are grouped in the Effects tab (Relief /
Camera / Light / Look; Camera is collapsed by default).
Effects that declare cameraInteraction (currently voxel-relief) get an
Orbit button on their effect header. While active, dragging in the Preview
orbits tilt/yaw freely in both directions (0.25°/px, same drag direction as
the 3D scene orbit),
Shift+drag pans the focus point, and the wheel dollies distance with a
smoothed target. Yaw and tilt wrap continuously instead of stopping at a
pole, and drag/dolly directions match the native 3D viewport. The eye orbits
at constant radius (distance 0.2–6), and the horizon stays level at every
yaw. Writes go through setPropertyValue, so
history batching (one undo step per drag) and keyframing behave exactly like
slider edits. The mode is ephemeral (engineStore.effectOrbitTarget), clears
on deselect, and hides for 3D clips.
Voxel traversal uses exact cell-boundary stepping with 2×2 supersampling, so
tall columns remain solid in profile views instead of breaking into dashed
segments or strong moiré patterns. Its Y-up orbit space is converted back to
the source texture’s Y-down coordinates when sampling, keeping text and video
upright at every camera angle. Rays that miss the relief remain transparent
instead of revealing a dim flat copy of the source behind the voxels; the
finite source floor remains available through Limit to Video.
For WebCodecs Fast export, display rotation from decoded VideoFrame sources
is materialized before multi-pass effects. The compositor then suppresses the
already-applied downstream rotation, keeping portrait Voxel Relief framing,
orientation, and camera animation identical between Preview and export. The
effect is still rendered at the active Preview/export target resolution;
columns controls voxel density, not output raster size.
Voxel Relief as a true 3D scene object
Section titled “Voxel Relief as a true 3D scene object”A clip with an enabled voxel-relief effect that is switched to 3D renders as a
scene object of kind voxel (instanced cubes with real depth) instead of a
flat plane — the scene camera replaces the effect’s virtual camera, and the
effect’s camera params plus temporalBlend/maxSteps/reset are ignored in
3D. The 2D post-effect is excluded for consumed voxel layers so it is not
applied twice. Voxel objects render in every scene view — the composite
preview (scene camera from an active Camera clip), the Edit view, and the
3D-edit viewports — and video-backed voxel fields sample the source through
the 2D-canvas copy, so real video frames drive the height field. Synthetic
scene layers use the viewport dimensions plus source-pixel scale compensation,
preventing portrait media from becoming a stretched, window-like slab in the
3D editor. Remaining
notes are tracked in docs/ongoing/Voxel-Relief-Orbit-3D.md.
Wall-clock animated effects can also set requiresContinuousRender. The engine keeps rendering live frames for active continuous effects while the playhead is parked, and it bypasses RAM Preview frame reuse so the animated output does not freeze.
Keyframing
Section titled “Keyframing”Numeric effect parameters can be keyframed through the timeline using the property path format:
effect.{effectId}.{paramName}EffectsTab reads interpolated values from the timeline store and writes animated numbers back through setPropertyValue.
The clip context menu supports Copy Effects and Paste Effects. This copies the full effect stack plus matching effect.* keyframes and pastes them onto the selected clip set.
- The empty
generate,time, andtransitioncategories are present in the type system without changing the registry shape.