Nodes whose primary output is a raster image — sources that generate pixels, and modifiers that transform them.
Generators
3D Cube (Test)
cube-3d-test
M0 render-bridge spike: a lit, spinning cube rendered by three.js on its own WebGL context and composited into the 2D graph. Proof-of-concept for the 3D context.
reads
time
flags
unstable
gotcha
Renders on its own isolated three.js WebGL context (a proof-of-concept render bridge), not the engine's shared 3D scene/camera graph.
gotcha
Cube size, position, and camera are fixed in code; only color, speed, metalness, and roughness are exposed as params.
gotcha
Spin comes from ctx.time * speed applied to both X and Y rotation, so it is deterministic per tick and safe for offline export.
gotcha
If the three.js renderer fails to construct (no WebGL2 or a lost context), the output degrades to a solid magenta debug clear instead of throwing.
Parameters
Name
Type
Default
Opacity
opacity
scalar
0 … 1
1
Color
color
color
"#ff6633"
Spin speed
speed
scalar
-4 … 4
0.6
Metalness
metalness
scalar
0 … 1
0.1
Roughness
roughness
scalar
0 … 1
0.45
Sockets
Direction
Name
Type
outputprimary
out
image
Cursor
cursor
Circular falloff field centered on the pointer, plus an aux velocity field encoded as RG (direction × magnitude, modulated by the same falloff). Radius and softness are in fractions of canvas width — circular on any aspect.
space
param:radius,aux:position=canvas01
flags
unstable
gotcha
radius is a fraction of canvas width (aspect-corrected), so the falloff disc stays circular on any aspect ratio.
gotcha
Velocity is timed against wall-clock performance.now(), not scene time, so it keeps responding while playback is paused and does not replay identically across two exports of the same timeline.
gotcha
velocity_vec and the aux velocity image's R/G are canvas-UV units per second scaled by velocity_scale, distinct from aux position which is authored canvas coordinates (y-down, aspect-uncorrected).
gotcha
velocity_smoothing 0 is instant/unsmoothed, 1 freezes the value entirely (EMA alpha = 1 − smoothing); default 0.3 is light smoothing.
gotcha
min/max remap the falloff output (default 0 outside, 1 at the cursor) and are not clamped, so max < min inverts the field.
Parameters
Name
Type
Default
Opacity
opacity
scalar
0 … 1
1
Radius
radius
scalar
0.001 … 1
0.15
Softness
softness
scalar
0 … 1
0.5
Min (outside)
min
scalar
-10 … 10
0
Max (at cursor)
max
scalar
-10 … 10
1
Velocity scale
velocity_scale
scalar
0 … 10
1
Velocity smoothing
velocity_smoothing
scalar
0 … 1
0.3
Sockets
Direction
Name
Type
outputprimary
out
image
outputaux
velocity
image
outputaux
velocity_vec
vec2
outputaux
position
vec2
Fluid Simulator
fluid-simulatorpolymorphic
2D Eulerian fluid (smoke / dye / ink in open water). Wire any mask/spline/shape into `deposit` to release dye; an image into `color` for its hues (alpha doubles as coverage when `deposit` is unwired). Takes the SAME force nodes as the Particle Simulator (Vortex/Wind/Gravity/Turbulence… — add slots in the panel) and Circle/Line/Image-Mask colliders as solid obstacles the flow routes around. The optional `field` input steers the fluid with an authored velocity field (Perlin curl / Spline Flow Field); the `velocity` aux emits the LIVE sim field in the same encoding, so Advect Points / Advect Image can ride the simulation. Advection-reflection keeps swirls energetic; `vorticity` adds small-scale swirl back. `buoyancy` makes dense dye rise (smoke). Runs while the timeline plays; restarting the timeline clears the tank.
reads
time
flags
simulation, unstable
gotcha
resolution downsamples the simulation grid (× canvas dims, min 8px per axis); only the final present/aux passes render back at full canvas resolution.
gotcha
Sim advances only while ctx.playing (or offline frame-stepping), or when the wired time input increases if drive_by_scene_time is on; a paused tweak re-presents the last state.
gotcha
Resets the whole tank (velocity, dye, pressure all cleared) on first evaluation or when ctx.time wraps back near 0 (scene loop).
gotcha
field and the velocity aux share the same signed-RG, y-down, canvas-width-relative encoding (VELOCITY_ENCODE_GLSL), so Advect Points/Advect Image can consume either directly.
gotcha
Falls back to a blank transparent output and a neutral velocity aux, with a one-time console.warn, when EXT_color_buffer_float is unavailable.
gotcha
force1..N/collider1..N use the same descriptor kinds as Particle Simulator (Gravity/Drag/Point/Vortex/Wind/Turbulence; Circle/Line/Image-Mask); slot count is fixed by forceCount/colliderCount.
Parameters
Name
Type
Default
Dye rate
inject_rate
scalar
0 … 20
6
Dye color
ink_color
color
"#ffffff"
Dye fade / sec
dissipation
scalar
0 … 1
0.02
Velocity fade / sec
velocity_dissipation
scalar
0 … 2
0.05
Vorticity (swirl)
vorticity
scalar
0 … 30
8
Buoyancy
buoyancy
scalar
-2 … 2
0
Field strength
field_strength
scalar
0 … 4
0.5
Speed
speed
scalar
0.1 … 4
1
Edges
edges
enum
"closed"
closed · open
Pressure iterations
pressure_iterations
scalar
8 … 60
24
Substeps / frame
substeps_per_frame
scalar
1 … 8
2
Resolution
resolution
scalar
0.1 … 1
0.5
Force slots
forceCount
scalar
0 … 6
1
Collider slots
colliderCount
scalar
0 … 4
0
View
view
enum
"composite"
composite · velocity
Drive by time input
drive_by_scene_time
boolean
false
Opacity
opacity
scalar
0 … 1
1
Sockets
Direction
Name
Type
input
deposit
deposit
mask
input
color
color
image
input
Field (guide)
field
image
input
force1
force1
force
outputprimary
out
image
outputaux
velocity
image
Gradient
gradientpolymorphic
Two-color gradient in linear, radial, polar or wave modes.
radial mode's distance-to-center is not aspect-corrected, so it reads as an ellipse on non-square canvases; only the wave ring sub-mode aspect-corrects its radius to stay round.
gotcha
angle_mod (and uv_in) are only exposed via resolveInputs in modes where they apply: linear and the directional (non-ring) wave sub-mode.
gotcha
angle_mod_amount converts the modulator's sampled red channel into a per-pixel radian offset that rotates the gradient axis (linear) or wave direction, added to the base angle.
gotcha
softness reshapes t through two nested pow() curves toward the endpoints; multipoint mode ignores softness entirely and blends colors directly by inverse-distance weighting.
gotcha
phase_animate drives phase from scene time (ctx.tick) via a [phase_start, phase_end]-frame loop window times phase_rate cycles; it loops seamlessly only when phase_rate is a whole number.
gotcha
multipoint supports at most 16 points (MAX_POINTS); any beyond that are silently dropped from the uniform arrays.
gotcha
uv_in, when wired, replaces the per-pixel v_uv sample every mode evaluates against; wiring a scalar broadcasts that single value to both UV components.
Generate images via OpenAI's gpt-image-2 with a chat interface in the param panel. Bring-your-own OpenAI key (Toolbox → User Preferences). Three optional reference image inputs feed the model as context. Outputs the currently-selected generation, or transparent when none is selected.
gotcha
compute() never reads the ref_a/ref_b/ref_c sockets; they only feed the generation request from the panel's chat interface, not the render graph.
gotcha
Output is driven entirely by selectedImagePath (a public bucket URL); empty means transparent output and immediately disposes any cached texture.
gotcha
On a URL change it first tries a synchronous panel-stashed ImageBitmap.
gotcha
On a cache miss it falls back to an async image fetch that emits transparent for that frame and fires pipeline-bump on completion.
gotcha
Requires the active user's own OpenAI API key (Toolbox -> User Preferences); generations are billed to and stored under that user's account.
translateX/Y, scaleX/Y, rotate and pivotX/Y apply as inverse TRS in output UV before the aspect fit, so cover's crop stays a movable window over the full-res source.
gotcha
fit=contain letterboxes with transparent alpha outside the image bounds; pixels outside the transformed unit square are also transparent.
gotcha
No file loaded emits fully transparent output, not black.
gotcha
exr_unpremultiply defaults on because EXR stores associated (premultiplied) alpha while the engine composites straight alpha.
gotcha
EXR layer/alpha decode is async; the previous texture keeps showing until the new decode lands, with decode progress folded into the node's fingerprint so the cache doesn't stick on stale data.
gotcha
uv_in, when wired, replaces v_uv before TRS/fit is applied, so a UV warp happens in output space ahead of the aspect fit; a scalar input broadcasts to both UV axes.
Parameters
Name
Type
Default
Opacity
opacity
scalar
0 … 1
1
Image
file
file
—
Layer
exr_layer
enum
""
Un-premultiply alpha
exr_unpremultiply
boolean
true
Fit
fit
enum
"cover"
cover · contain · stretch
Translate X
translateX
scalar
-1 … 1
0
Translate Y
translateY
scalar
-1 … 1
0
Scale X
scaleX
scalar
0.01 … 10
1
Scale Y
scaleY
scalar
0.01 … 10
1
Rotate (°)
rotate
scalar
-360 … 360
0
Pivot X
pivotX
scalar
0 … 1
0.5
Pivot Y
pivotY
scalar
0 … 1
0.5
Sockets
Direction
Name
Type
input
UV
uv_in
uv
outputprimary
out
image
outputaux
element
element
Lyapunov Fractal
lyapunov
Iterate the logistic map with a two-letter A/B sequence of r values and color each pixel by its Lyapunov exponent.
gotcha
uv.x maps to A in [a_min, a_max] and uv.y (Y-up) maps to B in [b_min, b_max]; the parameter rectangle fills the frame with no aspect correction.
gotcha
Sequence letters are A and B only (case-insensitive); other characters are dropped, an empty string falls back to AB, and more than 32 letters are truncated.
gotcha
warmup iterates without accumulating; iterations is the count in λ = mean(ln|r(1-2x)|); warmup+iterations is capped at 1024.
gotcha
color_mode=signed paints λ≈0 with color_stable, negative toward color_div, positive toward color_chaos; color_mode=exponent emits λ remapped through [lambda_lo, lambda_hi] as grayscale.
gotcha
x0=0.5 is the logistic-map critical point; a sequence that drives x to 0 or 1 (the r=4 edge with x0=0.5) is colored with color_div.
gotcha
uv_in replaces v_uv when wired (image R/G, or a scalar broadcast to both axes), so the sample is taken at that parameter-space coordinate.
Parameters
Name
Type
Default
Opacity
opacity
scalar
0 … 1
1
Sequence
preset
enum
"AABAB"
AABAB · AB · BBBBBAAAAA · BBABABA · Custom
Custom
sequence
string
"AABAB"
A min
a_min
scalar
0 … 4
2
A max
a_max
scalar
0 … 4
4
B min
b_min
scalar
0 … 4
2
B max
b_max
scalar
0 … 4
4
Warmup
warmup
scalar
0 … 800
200
Iterations
iterations
scalar
1 … 800
200
x₀
x0
scalar
0.001 … 0.999
0.5
Color
color_mode
enum
"signed"
Signed · Exponent
Stable
color_stable
color
"#f2d14b"
Chaos
color_chaos
color
"#1e3a8a"
Diverged
color_div
color
"#0a0612"
λ− scale
lambda_neg
scalar
0.01 … 4
0.6
λ+ scale
lambda_pos
scalar
0.01 … 4
0.5
λ lo
lambda_lo
scalar
-4 … 2
-1
λ hi
lambda_hi
scalar
-4 … 2
0.5
Sockets
Direction
Name
Type
input
UV
uv_in
uv
outputprimary
out
image
Noise
noise
Multi-algorithm fBm noise. Three outputs: `image` (rasterized canvas-wide), `value` (CPU scalar sampled at the `position` input — single number per frame), and `field` (per-pixel scalar shader expression sampled at `field_position` — wire into SDF Rotate.angle_field / SDF Twist.strength_field for true per-pixel/per-tile modulation; pair with SDF Repeat.cell_id for per-tile variation). The `field` output uses simplex regardless of the `type` param; image and value paths respect type. The `UV` input re-evaluates the noise at coordinates read from the wired value's R/G — wire another Noise (or any image) in for Blender-style domain warping/marbling.
space
in:position=uv01
reads
time
gotcha
field always samples simplex (SDF compiler only ports it); image and value respect type; field3d keeps perlin/value/simplex (perlin-deriv as perlin) and maps the rest to simplex.
gotcha
animated=true drives evolution from scene time on a closed loop between anim_start/anim_end frames, overriding the manual w slider.
gotcha
For type=flow, animated instead sweeps flow_time through one full 2*pi rotation over that loop; animated forces a recompute every tick.
gotcha
value is CPU-sampled at `position` (default 0.5,0.5 = canvas center) through the exact same scale/offset/aspect transform the image shader applies, so it matches the rendered pixel at that UV.
gotcha
The y sample is compressed by canvas aspect (width/height) before evaluating so noise cells stay square, so `scale` reads as cells-across-the-width regardless of aspect ratio.
gotcha
field3d is true 3D world-space noise (a different space from image/value/field): one world unit spans `scale` noise units, with w as evolution.
gotcha
Wiring an image into `UV` re-reads the sample position from its R/G channels instead of the canvas UV, for domain warping; a wired scalar broadcasts that one value to both axes.
gotcha
type=phasor: phasor_frequency is cycles per lattice cell, phasor_orientation is degrees (0=+X), phasor_isotropy 0=aligned to that heading and 1=±180° random.
Draw on the main canvas while this node is selected — brush, eraser, blur, fill, and eyedropper tools with editable brushes.
space
param:size=pixels
gotcha
compute() only blits the already-drawn snapshot bitmap; color, size, brush, and fill_tolerance shape the NEXT stroke in the Paint tool overlay and do nothing to strokes already painted.
gotcha
bg_mode=transparent passes straight-alpha strokes through untouched (composites over other layers, mattes cleanly to a mask); bg_mode=color composites them over `background` and is always opaque.
gotcha
An empty canvas (no strokes drawn yet) always outputs fully transparent, even in bg_mode=color; the background color only shows once a stroke exists.
gotcha
size is the brush diameter in canvas pixels at render resolution, so it does not scale automatically with output size.
Parameters
Name
Type
Default
Opacity
opacity
scalar
0 … 1
1
Color
color
color
"#ffffff"
Brush size
size
scalar
1 … 400
12
Fill tolerance
fill_tolerance
scalar
0 … 1
0.05
Background
bg_mode
enum
"transparent"
transparent · color
Bg color
background
color
"#000000"
Sockets
Direction
Name
Type
outputprimary
out
image
Physarum
physarumpolymorphic
GPU slime-mold (Physarum) transport network. Millions of agents sense a decaying trail field ahead-left / ahead / ahead-right, turn toward the strongest, step and deposit; the field diffuses and decays, and self-optimising vein networks emerge. Uses Sage Jenson's 36 Points parameterisation — every classic parameter is `base + scale * sensed^power`, so one algorithm covers 24 wildly different regimes. Pick a `preset`, then ride the four multipliers on top of it: `sense scale` is the most expressive (it slides the whole system between regimes), `turn` and `sensor angle` reshape the branching, and `scale` sets structure size — raise `blur passes` with it, since structure size is really the ratio of agent stride to diffusion width and `scale` alone just makes agents outrun the field. `custom` opens all 15 raw numbers. `agents` is a quality knob, not a look knob (the deposit is density-normalised), and `resolution` is fidelity above ~740px of sim height and a zoom below it. Wire a mask into `inject` to draw structure the agents colonise. Turn on `two points` and wire a mask into `blend` to run two different presets in different parts of the frame with a continuous frontier — a Circle driven by the Cursor node reproduces the original's interactive pen. Plays while the timeline runs; restarting the timeline reseeds. Algorithm: Jones 2010 / mxsage 36 Points; implementation ported from Etienne Jacob's interactive-physarum (CC BY-NC-SA 3.0).
reads
time
flags
simulation, unstable
gotcha
Point B (preset_b and its raw params) only affects the sim where `blend` is wired; unwired, `two_points` has no visible effect and every agent uses Point A.
gotcha
sensor_x offsets the sensing point along the agent's current heading; sensor_y offsets it by a fixed amount in world Y regardless of heading.
gotcha
Sensor/move distances (sd/md base+scale, sensor_x/y) scale with resolution above ~740px sim height to stay frame-relative; below it, low resolution just reads as zoomed in.
gotcha
respawn_rate is a per-step phase increment, not a probability: each agent teleports to a fresh random spot roughly every 1/respawn_rate steps, staggered by its seed phase.
gotcha
Diffuse radius follows the same resolution scaling as the distances (1..8 texels) and floors at 1 texel below the reference sim height, capping how far structure spreads per frame.
gotcha
view=trail shows the raw decayed trail channel; view=count applies the same count-to-intensity curve used by the color view and the count aux output.
Parameters
Name
Type
Default
Preset
preset
enum
"pure multiscale"
pure multiscale · hex hole open · vertebrata · star network · enmeshed singularities · waves upturn · more individuals · sloppy bucky · massive structure · speed modulation · transmission tower · ink on white · vanishing points · scaling nodule emergence · hyp offset · strike · clear spaghetti · point R · point S · point T · point U · point V · point W · point X · custom
Sensor distance base
sd_base
scalar
0 … 1200
0
Sensor distance power
sd_power
scalar
0 … 1400
4
Sensor distance scale
sd_scale
scalar
0 … 800
0.3
Sensor angle base
sa_base
scalar
0 … 240
0.1
Sensor angle power
sa_power
scalar
0 … 2080
51.32
Sensor angle scale
sa_scale
scalar
0 … 800
20
Rotation angle base
ra_base
scalar
0 … 240
0.41
Rotation angle power
ra_power
scalar
0 … 800
4
Rotation angle scale
ra_scale
scalar
0 … 520
0
Move distance base
md_base
scalar
0 … 160
0.1
Move distance power
md_power
scalar
0 … 1320
6
Move distance scale
md_scale
scalar
0 … 800
0.1
Sensor Y offset
sensor_y
scalar
-8 … 320
0
Sensor X offset
sensor_x
scalar
-16 … 640
0
Sense scale
sense_scale
scalar
0 … 2400
22
Two points
two_points
boolean
false
Preset B
preset_b
enum
"vertebrata"
pure multiscale · hex hole open · vertebrata · star network · enmeshed singularities · waves upturn · more individuals · sloppy bucky · massive structure · speed modulation · transmission tower · ink on white · vanishing points · scaling nodule emergence · hyp offset · strike · clear spaghetti · point R · point S · point T · point U · point V · point W · point X · custom
Grid of cells with nested concentric shape copies. Per-cell shape, copy count and base hue are seeded; copy scales animate over time. Pipe Scene Time into `time` to drive motion.
space
in:time=time
reads
time
flags
unstable
gotcha
time falls back to ctx.time when the time input is unwired, so the grid keeps animating during normal playback even without Scene Time wired.
gotcha
If useCircle/useSquare/useTriangle are all off, pickShape falls back to circle rather than an empty cell.
gotcha
copiesMin/copiesMax pick a per-cell copy count via hashed seed, clamped to 1..8; lockBaseShape pins only the outermost ring to scaleMax.
gotcha
cellSize is a 0..1 fraction of the shorter cell axis (aspect-preserving), not the full cell width or height.
gotcha
hueShift advances the ramp per concentric copy: rampPos = fract(baseHue + i*hueShift), so 0.17 on the default 6-stop ramp moves one stop per ring.
Fills the frame with a single color. The color square on the node opens a picker in place; the H/S/L/A row at the bottom nudges it without one.
gotcha
alpha (baked into the fill's u_color.a) and the universal opacity param both scale output alpha independently, so they multiply together.
Parameters
Name
Type
Default
Opacity
opacity
scalar
0 … 1
1
Color
color
color
"#808080"
Alpha
alpha
scalar
0 … 1
1
Sockets
Direction
Name
Type
outputprimary
out
image
Text
textpolymorphic
Renders text with a built-in transform. Wire a spline into the Path input to lay the text along it (Text on Path). Primary is the rasterized image; aux exposes an SDF (jump-flood) and the glyph outline as a spline.
boxWidth/boxHeight are per-axis uv01 fractions of the working canvas (width/height respectively), not aspect-corrected canvas01; 1×1 is the full canvas.
gotcha
translateX/Y, pivotX/Y, and rotate operate as raw per-axis UV offsets on the rasterized image (uv01), so rotate skews text on a non-square canvas.
gotcha
font_size, strokeWidth, and letter_spacing are literal canvas pixels at the working render resolution; they don't scale with boxWidth/Height or output size.
gotcha
sdf and spline aux build lazily only when consumed; dragging text while only primary/element are wired skips the JFA SDF and marching-squares contour work.
gotcha
A wired path or a maskDriven morph_mask axis forces a full re-rasterize every frame, bypassing the normal per-param signature cache.
gotcha
morph_mask (variable-font axis morph) only modulates the primary raster; element and instances aux always use the unmodulated base style.
gotcha
aux:spline is a simplified polyline (marching squares + ~0.4px RDP tolerance), not smooth beziers, so sharp zoom-ins show facets.
Parameters
Name
Type
Default
Opacity
opacity
scalar
0 … 1
1
Text
text
string
"Hello"
Font
font_family
enum
"Inter"
Inter · Roboto · Open Sans · Lato · Montserrat · Poppins · Work Sans · DM Sans · Nunito · Raleway · Oswald · Bebas Neue · Playfair Display · Merriweather · Crimson Text · Cormorant Garamond · Space Mono · JetBrains Mono · Helvetica · Arial · Georgia · Times New Roman · Courier New
Emits the default per-pixel (u, v) as a UV field. Feed it into UV-aware generators (Image Source, Gradient, Perlin) — with Math in UV mode sitting in between to warp, offset, or animate the coordinates.
gotcha
Only R and G carry u and v; B is always 0 and A is always 1, so anything reading the blue or alpha channel gets a flat constant.
Sockets
Direction
Name
Type
outputprimary
out
uv
Video Source
video-sourcepolymorphic
Load a video file and render its current frame. Sync the clock to scene time for deterministic playback (good for exports), or let it play on its own.
sync_to_scene_time drives currentTime to time*speed+start_offset (looped or clamped to duration); off, the element free-runs and only tracks scene play/pause.
gotcha
source_kind=sequence maps scene time to a frame index via seq_fps and forward-fills gaps between numbered frames; exr_layer/exr_unpremultiply apply only to EXR sequences.
gotcha
The video's own audio track stays muted unless this node's audio aux output is wired into Output's audio socket; volume only matters when audible.
gotcha
translateX/Y, scaleX/Y, rotate and pivotX/Y apply as inverse TRS in output UV before the fit; pixels outside the transformed unit square are transparent.
gotcha
fit=contain letterboxes with transparent alpha outside the video bounds, not opaque black.
gotcha
Offline export always pauses and hard-seeks to the exact frame and waits for the decode to settle before capture, regardless of playbackRate soft-sync used live.
gotcha
One <video> element has one currentTime, so this node is not retimeable; a wrapping Time Offset passes scene time through unshifted instead of retiming it.
Parameters
Name
Type
Default
Opacity
opacity
scalar
0 … 1
1
Source
source_kind
enum
"video"
video · sequence
Video
file
video_file
—
Image sequence
sequence
image_sequence
—
Sequence FPS
seq_fps
scalar
1 … 120
24
Layer
exr_layer
enum
""
Un-premultiply alpha
exr_unpremultiply
boolean
true
Fit
fit
enum
"cover"
cover · contain · stretch
Translate X
translateX
scalar
-1 … 1
0
Translate Y
translateY
scalar
-1 … 1
0
Scale X
scaleX
scalar
0.01 … 10
1
Scale Y
scaleY
scalar
0.01 … 10
1
Rotate (°)
rotate
scalar
-360 … 360
0
Pivot X
pivotX
scalar
0 … 1
0.5
Pivot Y
pivotY
scalar
0 … 1
0.5
Sync to scene time
sync_to_scene_time
boolean
true
Speed
speed
scalar
-4 … 4
1
Start offset (s)
start_offset
scalar
0 … 3600
0
Loop
loop
boolean
true
Volume
volume
scalar
0 … 1
1
Sockets
Direction
Name
Type
input
UV
uv_in
uv
outputprimary
out
image
outputaux
audio
audio
Voronoi
voronoipolymorphic
Worley/Voronoi cells from one of three point sources — an infinite procedural lattice, a CPU-scattered set (image-density placement + Lloyd relaxation, the former Fracture node), or an external Points input. Renders F1 / F2-F1 / F2 / cell-id / mask / position modes with selectable distance metric, and emits the true cell geometry as aux outputs: cell polygons (grouped, with per-cell driver), deduped edges, vertices, centers (area-scaled points), and the Delaunay neighbor graph. Geometry is the euclidean diagram and ignores the lattice warp/UV inputs; the Cell Bow param bulges cell edges outward (bubbles) or inward (pebbles).
reads
time
writes
attr:group, attr:driver
gotcha
offset_x/offset_y (lattice) pan in cell-sized units set by scale, not canvas-normalized distance; the same offset covers less canvas as scale increases.
gotcha
Aux geometry (cells/edges/vertices/centers/neighbors) is always the euclidean diagram; under metric=manhattan/chebyshev/minkowski it no longer overlays the rendered image.
gotcha
edge_bow only bulges the cells' spline edges outward (>0) or inward (<0); the rendered image and other aux outputs are unaffected.
gotcha
The warp input (lattice) distorts the rendered image per pixel but the geometry aux ignores it entirely; use scatter's density input for geometry-matched variable density.
gotcha
animated=true drives w from the scene tick along a seamless forward-only loop over anim_start..anim_end at anim_rate, overriding the manual w slider.
gotcha
cells stamp attr:group (stable per-cell id) and attr:driver (per-cell random, feeds Stroke/Rasterize ramp_by=driver); centers stamp the same group id plus area-relative scale.
gotcha
source=points truncates an incoming points value to the first 1024 points (MAX_POINTS) and logs a one-time console warning past that.
Parameters
Name
Type
Default
Opacity
opacity
scalar
0 … 1
1
Source
source
enum
"lattice"
lattice · scatter · points
Mode
mode
enum
"f2-f1"
f1 · f2-f1 · f2 · cells · mask · position
Distance metric
metric
enum
"euclidean"
euclidean · manhattan · chebyshev · minkowski
Minkowski N
minkowski_n
scalar
0.1 … 16
2
Scale
scale
scalar
0.5 … 80
8
Jitter
jitter
scalar
0 … 1
1
Offset X
offset_x
scalar
-50 … 50
0
Offset Y
offset_y
scalar
-50 … 50
0
Cell count
count
scalar
4 … 1024
80
Placement
placement
enum
"image"
image · uniform · random
Density bias
density_gamma
scalar
0.1 … 8
1.5
Density floor
density_floor
scalar
0 … 1
0.05
Lloyd iterations
relax
scalar
0 … 8
1
Seed
seed
scalar
0 … 1000
0
W (Evolution)
w
scalar
-100 … 100
0
Animated
animated
boolean
false
Start (frame)
anim_start
scalar
0 … 100000
0
End (frame)
anim_end
scalar
1 … 100000
120
Rate
anim_rate
scalar
0 … 10
1
Edge width
edge_width
scalar
0.0001 … 0.2
0.01
Falloff
falloff
scalar
0.1 … 8
1
Contrast
contrast
scalar
0.1 … 5
1
Invert
invert
boolean
false
Warp (dark)
warp_lo
scalar
0.1 … 8
0.5
Warp (bright)
warp_hi
scalar
0.1 … 8
2
Color A (low)
color_a
color
"#000000"
Color B (high)
color_b
color
"#ffffff"
Alpha
alpha
scalar
0 … 1
1
Cell bow (splines)
edge_bow
scalar
-1 … 1
0
Sockets
Direction
Name
Type
input
UV
uv_in
uv
input
Warp
warp
image
outputprimary
out
image
outputaux
cells
spline
outputaux
edges
spline
outputaux
vertices
points
outputaux
centers
points
outputaux
neighbors
spline
Watercolor Ink
watercolor-inkpolymorphic
Cellular-automaton watercolor / sumi ink simulation (Zhang et al. 1999). Wire any mask/spline/shape into `deposit` to lay down ink; water spreads through fibrous paper (nijimi), suspended ink rides and diffuses with it, and ink fixes permanently where the water dries. Wire an image into `color` and the deposited ink keeps its hues (white = clear water; with `deposit` unwired the image's alpha doubles as coverage). Low concentration = thin ink that wicks far along fibers; high = dense marks. `water map` scales the delivered water per cell (wired alone = pre-wet the sheet, wet-on-wet); `ink map` scales pigment concentration per cell (needs water to ride — dry areas deliver nothing). Sample rate 0 = continuous contact; above 0, the input (e.g. a video frame) is stamped as a full wash every 1/rate seconds and left to bloom/dry between stamps. Plays while the timeline runs; restarting the timeline clears the sheet.
reads
time
flags
simulation, unstable
gotcha
resolution runs the sim grid at a fraction of canvas size (0.1–1); substeps and evap/rewet rates auto-scale by simScale² so bloom and drying stay roughly resolution-independent.
gotcha
Requires EXT_color_buffer_float; without it the simulation is disabled and the node just outputs a flat, blank paper-color image.
gotcha
Sim state (wet ink, dried ink, paper) persists per node in float32 textures across frames; a timeline restart (scene time wrapping back near zero) clears the sheet to dry and blank.
gotcha
drive_by_scene_time replaces the default timeline-playing gate with a wired `time` scalar input; the sim advances a substep only when that value increases.
gotcha
Changing fiber_count or paper_seed regenerates the paper texture and resets the sheet to dry, even mid-playback.
gotcha
lifetime=0 makes dried ink permanent; above 0, marks older than lifetime decay to about 1% of their value over `dissolve` seconds.
Parameters
Name
Type
Default
Deposit water
deposit_water
scalar
0 … 200
60
Ink concentration
dip_concentration
scalar
0.02 … 1
0.5
Sample rate (Hz)
sample_rate
scalar
0 … 30
0
Flow rate
alpha
scalar
0.05 … 1
0.8
Diffusion
beta
scalar
0 … 0.25
0.12
Evaporation
evap_rate
scalar
0 … 0.05
0.004
Re-wetting
rewet
scalar
0 … 0.05
0
Fade / sec
fade
scalar
0 … 1
0
Dried lifetime (s)
lifetime
scalar
0 … 60
0
Dissolve (s)
dissolve
scalar
0.05 … 10
1
Substeps / frame
substeps_per_frame
scalar
1 … 16
6
Resolution
resolution
scalar
0.1 … 1
0.5
Paper coarseness
fiber_count
scalar
0 … 200000
50000
Paper seed
paper_seed
scalar
0 … 1000000
0
Wet ink strength
wet_strength
scalar
0 … 2
0.55
Dried ink strength
dried_strength
scalar
0 … 2
0.9
Ink color
ink_color
color
"#000000"
Paper color
paper_color
color
"#f7f7f6"
Paper background
paper_bg
boolean
true
View
view
enum
"composite"
composite · water · ink · dried · paper
Drive by time input
drive_by_scene_time
boolean
false
Opacity
opacity
scalar
0 … 1
1
Sockets
Direction
Name
Type
input
deposit
deposit
mask
input
color
color
image
input
water map
water_map
mask
input
ink map
ink_map
mask
outputprimary
out
image
Webcam Source
webcam-source
Live webcam feed via getUserMedia. First eval triggers the browser permission prompt. Mirror toggle defaults on to match how video-chat tools render the feed.
space
param:offsetX,param:offsetY=uv01
flags
unstable
gotcha
offsetX/offsetY pan in per-axis UV fractions before the fit, not aspect-corrected; zoom scales about the canvas center.
gotcha
mirror flips the sample X axis after offset/zoom is applied, so a positive offsetX pans the opposite screen direction while mirror (the default) is on.
gotcha
Switching facing tears down the current getUserMedia stream and re-requests camera permission for the new facing; audio is never requested.
gotcha
Live capture only, so this node is not retimeable; a wrapping Time Offset passes the current frame through unshifted instead of retiming it.
Parameters
Name
Type
Default
Opacity
opacity
scalar
0 … 1
1
Facing
facing
enum
"user"
user · environment
Fit
fit
enum
"cover"
cover · contain · stretch
Offset X
offsetX
scalar
-1 … 1
0
Offset Y
offsetY
scalar
-1 … 1
0
Zoom
zoom
scalar
0.01 … 10
1
Mirror
mirror
boolean
true
Sockets
Direction
Name
Type
input
UV
uv_in
uv
outputprimary
out
image
Modifiers
Adaptive Pixelate
adaptive-pixelate
Pixelate with a non-constant grid: block size is driven by a luminance map (the Size Map input, or the image's own luminance). Quadtree mode splits blocks 4-ways where the map calls for detail; lattice mode crowds full-span rows/columns; uniform mode is a plain grid. Emits one point per block (center, scale, level) for building systems downstream.
size/block_min/block_max are absolute pixels at render resolution and do not scale with output size.
gotcha
Brighter size_map (or source luminance) drives smaller blocks (more detail) by default; invert flips that mapping, gamma reshapes the response curve.
gotcha
lattice_axes=columns/rows locks the other axis to a single full-span block instead of a grid; only 'both' crowds rows and columns independently.
gotcha
sample=average filters through a private mip chain at each cell's geometric-mean LOD, avoiding aliasing on large blocks; sample=center is a single texel tap at the cell center.
gotcha
aux:points is built every evaluation even when unwired, since the cell grid is already CPU-side for the image pass — it is not gated behind whether anything consumes it.
gotcha
aux:points positions are cx/canvasWidth, cy/canvasHeight (a per-axis fraction), not the aspect-corrected canvas01 convention other point sources use.
gotcha
On a driver readback failure (e.g. context loss) this silently falls back to a plain uniform grid at block_max instead of erroring.
Parameters
Name
Type
Default
Mode
mode
enum
"quadtree"
uniform · quadtree · lattice
Block size (px)
size
scalar
2 … 256
16
Min block (px)
block_min
scalar
2 … 128
8
Max block (px)
block_max
scalar
8 … 512
64
Invert map
invert
boolean
false
Map response
gamma
scalar
0.25 … 4
1
Axes
lattice_axes
enum
"both"
both · columns · rows
Sampling
sample
enum
"center"
center · average
Opacity
opacity
scalar
0 … 1
1
Sockets
Direction
Name
Type
input*
image
image
image
input
Size Map
size_map
mask
outputprimary
out
image
outputaux
points
points
Advect Image
advect-image
Flow an image along a velocity field: each pixel back-traces `steps` samples through the field (re-sampled every step, so content follows the field's curves — unlike Displace's single push). Deterministic and scrub-safe: `distance` is the total flow, keyframe it 0→N to animate content streaming along the field. Field modes match Advect Points (`vector` = signed-RG velocity from Perlin curl / Spline Flow Field, `angle` = luminance heading, `gradient` / `contour` = flow toward / around brightness). Optional speed image multiplies flow by its luminance. The `uv` aux carries the final warp for reuse in any uv consumer.
space
param:distance=canvas01
gotcha
With no field wired, steps collapses to 0, the trace becomes an identity uv map, and pass 2 is a straight copy of the source image.
gotcha
distance is the TOTAL flow across all steps in aspect-corrected canvas-width units, not a per-step amount; keyframe it 0->N to stream content along the field without touching steps.
gotcha
steps controls curve fidelity: each step re-samples the field, so steps=1 degenerates to a single Displace-style push instead of following the field's curves.
gotcha
speed multiplies flow by the speed image's luminance (dot with Rec.709 weights) each step, ignoring its color and alpha.
gotcha
gradient/contour modes derive direction from a finite-difference of field luminance (GRAD_EPS = 0.004 of canvas width), so a noisy or low-res field image causes visible jitter.
gotcha
edge=transparent drops samples that land outside [0,1] to alpha 0; clamp/wrap/mirror instead remap them back inside range.
gotcha
angle_turns/angle_offset only affect field_mode=angle; midlevel only affects field_mode=vector.
gotcha
aux:uv is built every evaluation regardless of whether it's wired, since this node is cacheable and a cache hit would otherwise serve a stale empty uv once something gets wired to it.
Parameters
Name
Type
Default
Field
field_mode
enum
"vector"
vector · angle · gradient · contour
Distance
distance
scalar
0 … 1
0.08
Steps
steps
scalar
1 … 64
12
Invert flow
invert
boolean
false
Angle range (turns)
angle_turns
scalar
0 … 4
1
Angle offset (turns)
angle_offset
scalar
-1 … 1
0
Midlevel
midlevel
scalar
0 … 1
0.5
Edge
edge
enum
"clamp"
transparent · clamp · wrap · mirror
Opacity
opacity
scalar
0 … 1
1
Sockets
Direction
Name
Type
input*
image
image
image
input*
Field
field
image
input
Speed field
speed
image
outputprimary
out
image
outputaux
uv
uv
Apply LUT
lut
Apply a .cube 3D LUT (color grade) to the image. The optional log2 HDR shaper applies OCIO-baked (shaper + cube) LUTs to scene-linear footage.
gotcha
shaper_min_stops/shaper_max_stops only apply when shaper=log2; with shaper=none, input is clamped to the LUT's own declared domain (usually 0..1) instead.
gotcha
No LUT loaded, or text that fails to parse, falls back to a straight passthrough copy that silently ignores intensity and shaper.
gotcha
The 3D texture is (re)parsed and re-uploaded only when the .cube text changes, cached per node instance; a failed parse is also cached to avoid re-parsing every frame.
gotcha
The volume uploads as RGBA16F with trilinear filtering, so LUT outputs above 1.0 survive unclamped for HDR-to-HDR transforms.
Parameters
Name
Type
Default
LUT (.cube)
lut
lut_file
—
Intensity
intensity
scalar
0 … 1
1
HDR shaper
shaper
enum
"none"
none · log2
Shaper min (stops)
shaper_min_stops
scalar
-16 … 0
-10
Shaper max (stops)
shaper_max_stops
scalar
0 … 16
6.5
Sockets
Direction
Name
Type
input*
image
image
image
outputprimary
out
image
ASCII
asciipolymorphic
Render the input image as a grid of glyphs — text characters from a palette string (any font), or each image in a connected image_group. Glyph and per-cell background colors source from flat / the cell's own color / a color ramp driven by index, seeded hash, position, brightness, or a wired image. Brightness remapping, per-cell modulators, and aux index/brightness outputs match the Array node's conventions.
gotcha
Ascii's index aux always uses column-first cell ordering; it only matches Array's aux index when Array's direction is set to flow-columns, not Array's default flow-rows.
gotcha
brightness aux is the in_min/in_max remap only — it ignores out_min/out_max and the blank threshold, so it can be nonzero for cells the main output renders fully transparent.
gotcha
threshold gates the whole cell (glyph and background) to fully transparent below it, not just the glyph; 0 (default) disables the gate.
gotcha
In image_set mode fg_source/fg_color/fg_ramp have no effect: the atlas item's own RGBA replaces the glyph outright, only the background layer still composites.
gotcha
bg_transform makes the background fill only the glyph's scaled/rotated tile instead of the whole cell rect, so glyph_scale < 1 opens transparent gutters between cells.
gotcha
ramp_by=position projects the cell center on a steerable axis Y-DOWN (angle 0 = left-to-right, 90 = top-to-bottom), matching the per-subpath ColorRampBy position mode.
Parameters
Name
Type
Default
Mode
mode
enum
"text"
text · image_set
Palette
text
string
" .:-=+*#%@"
Font
font_family
enum
"Menlo"
Inter · Roboto · Open Sans · Lato · Montserrat · Poppins · Work Sans · DM Sans · Nunito · Raleway · Oswald · Bebas Neue · Playfair Display · Merriweather · Crimson Text · Cormorant Garamond · Space Mono · JetBrains Mono · Helvetica · Arial · Georgia · Times New Roman · Courier New
Figma-style auto layout: stacks element children horizontally or vertically with alignment, padding, and gap. Children size as fixed (layout units), hug-contents, or fill-container; the aux element output makes layouts nestable. Plain image wires coerce to full-canvas elements — use per-slot trim or a Frame node to size them.
gap, padding, width/height, cornerRadius and strokeWidth are layout units (1 unit = min(canvasW,canvasH)/1000 px), scaling with project resolution, unlike raw pixel params.
gotcha
translateX/Y and pivotX/Y are per-axis UV fractions (uv01, not aspect-corrected) applied directly to the container's own v_uv, not width-relative canvas01.
gotcha
The aux element output is the nesting hook: a parent Auto Layout's fill slot re-solves this container at the granted size; hug sizes measure children instead.
gotcha
The primary output is a full-canvas image with the container centered and transformed; for nesting, wire the aux element output instead of the primary.
gotcha
Each item's trim crops it to its cached alpha bounding box before layout, shrinking its hug size to the non-transparent region.
Remove the background from an image or video. RMBG (still) runs BRIA's model locally via Transformers.js — Bake captures the upstream frame + alpha once. RVM (video) runs PeterLin's Robust Video Matting ONNX in the browser; Bake walks an in/out range and recycles the model's recurrent states so the matte stays temporally consistent. Live `feather` / `threshold` tweak the edge without a re-bake. RVM bakes are session-only (reopen → re-bake). Outputs the cutout (primary) plus the mask as both a typed mask aux and a grayscale image aux.
space
param:feather=uv01
reads
time
gotcha
compute() never runs ML inference; RMBG/RVM only run via the Bake button in the custom param panel. feather/threshold are the only per-frame live params.
gotcha
feather is a 9-tap blur offset scaled by the mask's OWN resolution (u_invMask), not canvas resolution, so a downsampled RVM mask blurs more per canvas pixel than a full-res one.
gotcha
Passthrough (no bake yet, or a missing bitmap) fills the mask and mask_image aux to opaque white, meaning everything reads as foreground.
gotcha
threshold's edge sharpness is not linear: the smoothing knee is WIDEST (softest edge) at threshold=0.5 and narrows toward a hard cutoff near 0.1 or 0.9.
Slice the image into bento-box rectangles (recursive cuts driven by a luminance map — the Size Map input, or the image's own luminance) and offset every piece along a seeded scatter direction by Fac: 0 = assembled, 1 = split apart. Animate Fac to assemble or shatter the image. Steps > 1 makes pieces travel an axis-aligned staircase (2 = slide in sideways, then drop into place), with one easing curve per step. Emits one point per piece at its animated center for driving systems downstream.
distance is a fraction of canvas width (distance x W); piece_min/piece_max/gap are literal raster pixels that stay fixed as output resolution changes.
gotcha
The cut grid is cached by a layout signature plus the driver's (size_map or image) identity; only geometry params rebuild it, not fac/steps/easing.
gotcha
steps >= 2 alternates horizontal/vertical legs per first_axis, splitting fac's 0..1 domain into equal per-leg ranges each shaped by easing.
gotcha
aux:points' y is (cy+offY)/H, a plain UV fraction, not the aspect-corrected canvas01 convention other points outputs use, so it reads off on non-square canvases.
gotcha
piece_min is silently raised toward sqrt(W*H/65536) to keep the worst-case piece count bounded, regardless of the slider value.
Bevel & Emboss — fake-3D raised edge from a height source. Outer / Inner / Emboss / Pillow Emboss styles. Two lights (each with angle, elevation, opacity) shade the height field with shared highlight + shadow colors and blend modes. Outer/Inner/Pillow use a JFA-derived signed-distance height (cached per input image); Emboss uses the input's luminance directly.
space
param:depth,param:soften,param:feather=pixels
gotcha
depth (px) sets bevel reach; the height gradient is rescaled by depth so relief strength (face angle) stays consistent as depth changes, in every style including emboss.
gotcha
style=emboss skips the JFA distance field entirely and reads the source's alpha-weighted luminance as height directly; depth still scales relief strength but not falloff reach.
gotcha
Wiring the optional height input JFAs its OWN alpha instead of the main image's, decoupling the relief shape from the visible image.
gotcha
outer-bevel and pillow-emboss extend output alpha outward past the source shape, up to a depth-sized band, so the raised rim is not clipped by the original alpha.
gotcha
The JFA distance field is cached by the height source's object identity; an animated source (video, generative) recomputes the full JFA pass every frame.
Mip-chain bloom (COD / UE5 / Unity HDRP technique). Soft-knee threshold + Karis-average downsample + 9-tap tent upsample give a crisp bright core with hundreds of pixels of soft tail at constant cost. Optional per-mip tint, anamorphic stretch, and lens dirt overlay. Quality picks where the pyramid starts: balanced/performance trade the glow's finest detail octave(s) for most of the pre-composite GPU cost, keeping the halo width unchanged.
flags
gates-outputs
gotcha
levels is capped so the smallest mip stays a few pixels wide, and quality=balanced/performance shrink it further to hold the halo width — effective levels can undercut the param.
gotcha
anamorphic only squashes the tent's cross axis down to 15% at ±1, never to 0, so a faint bleed on the off-axis remains even at the extremes.
gotcha
quality=performance undersamples the threshold pass (4 taps over an 8x8 block), so isolated 1-2px highlights can shimmer in motion.
gotcha
karis_average only changes the first downsample step; every later step always uses the plain COD tap weights.
Parameters
Name
Type
Default
Threshold
threshold
scalar
0 … 2
0.7
Soft Knee
soft_knee
scalar
0 … 1
0.5
Intensity
intensity
scalar
0 … 5
1
Levels
levels
scalar
1 … 8
6
Karis (firefly fix)
karis_average
boolean
true
Quality
quality
enum
"high"
high · balanced · performance
Anamorphic
anamorphic
scalar
-1 … 1
0
Core Tint
tint_low
color
"#ffffff"
Halo Tint
tint_high
color
"#ffffff"
Tint Amount
tint_amount
scalar
0 … 1
0
Sockets
Direction
Name
Type
input*
image
image
image
input
Lens Dirt
lens_dirt
image
outputprimary
out
image
outputaux
bloom_only
image
Blur
blurpolymorphic
Blur with selectable kernel. Gaussian for a plain soft blur, or Bokeh for true circular apertures (disc, ring, soft) with the flat-topped shape and hot rim a Gaussian cannot produce. Filters in premultiplied linear light.
space
param:radius=pixels
gotcha
radius is in pixels at render resolution and does not scale with output size; Gaussian sigma = radius/2, capped at 64 taps per side (radius ≈43).
gotcha
The kernel input only exists when mode=convolve; in gaussian/bokeh modes there is nothing to wire it to.
gotcha
Filters in premultiplied linear light, so transparent edges do not darken but results differ from an sRGB-space blur.
Parameters
Name
Type
Default
Mode
mode
enum
"gaussian"
gaussian · bokeh · convolve
Radius (px)
radius
scalar
≥ 0
0
Shape
shape
enum
"disc"
disc · ring · soft · hexagon · octagon · cats_eye · star
Components
components
scalar
1 … 4
3
Rank
rank
scalar
1 … 8
4
Rotation
rotation
scalar
-180 … 180
0
Normalize kernel
normalize
boolean
true
Ring
ring
scalar
0 … 1
0.5
Blur in linear light
linearize
boolean
true
Opacity
opacity
scalar
0 … 1
1
Sockets
Direction
Name
Type
input*
image
image
image
outputprimary
out
image
Chromatic Aberration
chromatic-aberration
Split the red and blue channels away from green to fake lens dispersion or a glitchy RGB shift. Radial (grows from a center) or directional (uniform angled shift).
space
param:amount,param:center=uv01
gotcha
amount/center are UV fractions added straight to v_uv with no aspect term, so the same amount shifts a different fraction of width vs height.
gotcha
mode=directional ignores center and falloff entirely — only angle drives the shift.
gotcha
falloff only reshapes the radial ramp (0 = uniform amount everywhere, >1 = edge-heavy) and has no effect in directional mode.
gotcha
Out-of-range taps sample transparent black; output alpha is the max of the three channel taps to avoid dark edge fringing.
Parameters
Name
Type
Default
Amount
amount
scalar
0 … 0.1
0.004
Mode
mode
enum
"radial"
radial · directional
Center
center
vec2
[0.5,0.5]
Falloff
falloff
scalar
0 … 2
1
Angle
angle
scalar
-180 … 180
0
Opacity
opacity
scalar
0 … 1
1
Sockets
Direction
Name
Type
input*
image
image
image
outputprimary
out
image
Coherence Shock
shock-filter
Painterly sharpening: smooths ALONG the image's flow while pushing pixels toward their local light/dark extreme ACROSS it, so soft gradients collapse into crisp, fluid brush edges — the operator behind most 'hand-painted' looks; stack after Kuwahara or Flow Bilateral. Steered by the `field` input (Image Flow Field or any velocity field) or an internal estimate when unwired. `Iterations` compounds the effect (deterministic — safe to scrub and export), `Radius` sets how far the sharpening reaches, `Smooth along` the per-iteration flow smoothing, `Amount` blends the shock against the smoothed base.
radius and smooth_along are pixel taps at render resolution (u_invRes-scaled loops capped at 16 taps per side), so they do not scale with output size.
gotcha
Without a `field` input it estimates its own flow field once (preBlur 1, `smooth` controls its smoothing) — `smooth` is ignored the moment `field` is wired.
gotcha
iterations compounds smooth+shock passes in one compute (1-8, clamped); the field is sampled from the ORIGINAL source each iteration, not re-estimated, so animation stays stable.
gotcha
The shock pass picks dilation or erosion per pixel from the sign of the second luminance derivative across the flow, then blends toward the extreme sample by `amount`.
gotcha
Luminance sampling is coverage-weighted (lum × alpha) and the amount blend runs in premultiplied space, so transparent surrounds never win a dilation.
Parameters
Name
Type
Default
Iterations
iterations
scalar
1 … 8
3
Radius
radius
scalar
1 … 16
2
Smooth along
smooth_along
scalar
0 … 10
2
Amount
amount
scalar
0 … 1
1
Internal smooth
smooth
scalar
0 … 32
4
Opacity
opacity
scalar
0 … 1
1
Sockets
Direction
Name
Type
input*
image
image
image
input
Field
field
image
outputprimary
out
image
Color Correction
color-correction
Hue, saturation, brightness, contrast, and per-channel RGB curves.
gotcha
Order: white balance, lift/gamma/gain/offset wheels, per-zone exposure and saturation, brightness/contrast (pivoted), midtone detail, hue/saturation, RGB curves last.
gotcha
Each wheel's balance (X,Y) reads as a clockwise angle from "up" (red at top, matching the panel's hue disc), with radius as push strength.
gotcha
Per-wheel Sat/Exp are blended by luma zone weight (dark/mid/light) — a wheel barely touches pixels outside its own zone.
gotcha
The saturation param is a separate legacy HSV control, independent of the four wheels' own per-zone Sat fields.
Parameters
Name
Type
Default
Hue (°)
hue
scalar
-180 … 180
0
Saturation
saturation
scalar
0 … 50
1
Contrast
contrast
scalar
0 … 4
1
Brightness
brightness
scalar
-1 … 1
0
RGB Curves
curves
curves
(complex)
dark balance X
darkX
scalar
-1 … 1
0
dark balance Y
darkY
scalar
-1 … 1
0
dark master
darkLum
scalar
-2 … 2
0
dark exposure
darkExp
scalar
-2 … 2
0
dark saturation
darkSat
scalar
0 … 2
1
shadow balance X
shadowX
scalar
-1 … 1
0
shadow balance Y
shadowY
scalar
-1 … 1
0
shadow master
shadowLum
scalar
-2 … 2
0
shadow exposure
shadowExp
scalar
-2 … 2
0
shadow saturation
shadowSat
scalar
0 … 2
1
light balance X
lightX
scalar
-1 … 1
0
light balance Y
lightY
scalar
-1 … 1
0
light master
lightLum
scalar
-2 … 2
0
light exposure
lightExp
scalar
-2 … 2
0
light saturation
lightSat
scalar
0 … 2
1
global balance X
globalX
scalar
-1 … 1
0
global balance Y
globalY
scalar
-1 … 1
0
global master
globalLum
scalar
-2 … 2
0
global exposure
globalExp
scalar
-2 … 2
0
global saturation
globalSat
scalar
0 … 2
1
Temp
temp
scalar
-1 … 1
0
Tint
tint
scalar
-1 … 1
0
Pivot
pivot
scalar
0 … 1
0.5
Midtone Detail
md
scalar
-1 … 1
0
Black Offset
boffset
scalar
-1 … 1
0
Sockets
Direction
Name
Type
input*
image
image
image
outputprimary
out
image
Color Ramp
color-ramp
Remaps the input's luminance through a gradient of user-defined color stops. Offset slides the ramp; values past 1 wrap so the gradient loops.
gotcha
Remaps by luminance (Rec.709 weighted), not per channel; the source's own alpha is preserved and multiplied by the ramp stop's alpha.
gotcha
offset=0 pins t=1 exactly to the last stop; any nonzero offset wraps the whole 0..1 domain via fract(), shifting what shows at the extremes.
gotcha
Up to 16 stops — extras are silently dropped after sorting by position.
gotcha
The ramp aux always emits the sorted stop list, even with nothing wired into image — it works as a pure palette source into Stroke/Rasterize Spline.
Convert between color spaces (sRGB, linear, ACEScg, ACES2065-1, Rec.709, Display P3) with an optional view transform (ACES / AgX / Filmic tone mapping) — the display step for scene-linear EXR renders.
gotcha
view=None performs a pure gamut+transfer conversion with no clamping, so scene-linear HDR passes through unclamped when both ends are linear; ACES/AgX/Filmic all clamp to [0,1].
gotcha
"Rec.709" shares its gamut primaries with Linear sRGB/sRGB — choosing it only swaps the transfer curve to BT.1886 (gamma 2.4).
gotcha
The view transform runs in linear sRGB between the two gamut conversions, so it tone-maps before the `to` gamut/transfer is applied.
Glitch-melt two clips into each other. Wire two image inputs, then in the panel Bake each clip into the node, drag the two clips on the mini-timeline so they overlap, and the overlap is moshed: the incoming clip's motion warps a frozen frame of the outgoing clip (optical-flow advection). Flow Scale sets the smear distance, Smear its length, Decay its falloff, Refresh how fast the real incoming pixels bleed back. Preview plays forward live; Mosh bakes the result for clean scrubbing and export. (Inputs are session-only — reopen → re-bake.)
space
param:flowScale=uv01 param:searchRadius=pixels
reads
time
flags
simulation
gotcha
engine=codec is accepted and serialized but currently renders identically to flow; the panel disables selecting it (M2 stub).
gotcha
flowScale is a uv01 fraction (max per-pixel displacement, no aspect term); searchRadius (block estimator) is a texel count that does not scale with output size.
gotcha
aStart/aLen/bStart/bLen/sourceInA/B and bakeInA/OutA/bakeInB/OutB are hidden params written only by the node's custom timeline panel, not the normal param list.
gotcha
Live (not-yet-output-baked) mode only accumulates forward: scrubbing before the last built frame reseeds from clip A's frozen frame at the overlap start.
gotcha
If a needed strip frame isn't decoded yet, the node holds the last accumulated frame (or clears to transparent) instead of blocking, and retries next eval.
Parameters
Name
Type
Default
Engine
engine
enum
"flow"
flow · codec
Algorithm
estimator
enum
"gradient"
gradient · residual · block
Search
searchRadius
scalar
1 … 8
4
Flow Scale
flowScale
scalar
0 … 1
0.08
Smear
smear
scalar
1 … 64
8
Decay
decay
scalar
0 … 1
0.85
Refresh
refresh
scalar
0 … 1
0.05
Remove I-frames
iframeRemoval
boolean
true
P-frame Dup
pframeDup
scalar
0 … 8
0
Sockets
Direction
Name
Type
input
clip A
imageA
image
input
clip B
imageB
image
outputprimary
out
image
Depth Anything
depth-anything
Estimate a depth map from an image locally via Transformers.js (Depth Anything V2). The header toggle switches the output between the depth map (grayscale, near=white) and a normal map derived from the depth gradient. Invert flips near/far; Near/Far set the depth black/white points. For animated inputs, Preview runs depth on the current frame and Bake runs the model over an in/out frame range and caches a depth map per frame (held in memory for this session — reopen → re-bake). Note: the model normalizes each frame independently, so brightness can drift over a clip.
reads
time
gotcha
precision (fp32/fp16/q8) only affects inference quality when the panel bakes or previews; compute() and the render path ignore it entirely.
gotcha
near/far only affect outputMode=depth; the normal map uses only invert and normalStrength and ignores near/far.
gotcha
If far <= near, the denominator clamps to a 1e-4 epsilon instead of erroring, blowing the depth remap out to near-solid black or white.
gotcha
Before any Preview/Bake, the primary passes the input through unchanged while the aux depth mask reads solid 0, not transparent or undefined.
Parameters
Name
Type
Default
Output
outputMode
enum
"depth"
depth · normal
Model
model
enum
"v2-small"
v2-small · v2-base · v2-large
Quality
precision
enum
"fp32"
fp32 · fp16 · q8
Invert
invert
boolean
false
Near
near
scalar
0 … 1
0
Far
far
scalar
0 … 1
1
Normal Strength
normalStrength
scalar
0 … 8
1
Sockets
Direction
Name
Type
input*
image
image
image
outputprimary
out
image
outputaux
depth
mask
Displace
displacepolymorphic
Offset by a vector read from a displacement field. Wire an image and each pixel is pushed; wire a spline or points value and each anchor/point is pushed (sampled at its own UV). Channel X/Y pick the per-axis channels (RG vector field, or luminance for both); midlevel is the neutral value (0.5 for signed maps). Rotate (optional) also spins from the map's luminance — images around the frame center, points via per-point rotation, splines via each anchor's handles.
amountX/Y are per-axis UV fractions ((channel − midlevel) × amount), not aspect-corrected: 0.05 pushes 5% of width in X and 5% of height in Y.
gotcha
Polymorphic on the image socket: an image is pushed per pixel; a spline or points value is pushed per anchor/point, each sampling the map at its own UV.
gotcha
midlevel is the neutral map value (0.5 for signed 8-bit maps, 0 for unsigned); channelX/Y pick which map channels drive each axis.
gotcha
rotate spins from the map's luminance: images about the frame center, points via per-point rotation, splines via anchor handles.
Parameters
Name
Type
Default
Amount X
amountX
scalar
-1 … 1
0.05
Amount Y
amountY
scalar
-1 … 1
0.05
Channel X
channelX
enum
"r"
r · g · b · a · luminance
Channel Y
channelY
enum
"g"
r · g · b · a · luminance
Midlevel
midlevel
scalar
0 … 1
0.5
Rotate
rotate
boolean
false
Amount (°)
rotateAmount
scalar
-360 … 360
180
Edge
wrap
enum
"clamp"
transparent · clamp · mirror
Sockets
Direction
Name
Type
input*
image
image
image
input*
displace
displacement
image
outputprimary
out
image
Dither
dither
Quantize the input image with error-diffusion or ordered dithering.
gotcha
pixel_scale downsamples to width/height divided by pixel_scale before dithering, then upscales with nearest filtering for blocky pixels, not a blur.
gotcha
color_mode=false quantizes to black/white using threshold (1..255); color_mode=true quantizes each RGB channel to levels steps instead and ignores threshold.
gotcha
spread only scales the diffused error in the kernel algorithms (floyd-steinberg/atkinson/stucki/burkes/sierra/jarvis); ordered and threshold ignore it.
gotcha
algorithm=ordered uses an 8x8 Bayer matrix against threshold or levels; it never reads spread.
Extract edges via Sobel or Prewitt 3×3 gradient convolution. Output is grayscale gradient magnitude — brighter = stronger edge. Threshold clamps weak responses to zero for binary edge maps.
gotcha
threshold clips the strength-scaled magnitude, not the raw gradient, so raising strength also lowers the effective threshold.
gotcha
Samples at a fixed 1-pixel offset (1/src.width, 1/src.height), so edge width is always one source pixel and does not scale with output resolution.
gotcha
Output is fully opaque (alpha forced to 1) and grayscale (R=G=B=magnitude); the source's own alpha channel is discarded.
Parameters
Name
Type
Default
Algorithm
algorithm
enum
"sobel"
sobel · prewitt
Strength
strength
scalar
0 … 10
1
Threshold
threshold
scalar
0 … 1
0
Sockets
Direction
Name
Type
input*
image
image
image
outputprimary
out
image
Flow Bilateral
flow-bilateral
Edge-preserving smoothing aligned to the image's flow: a 1D bilateral filter runs across the local edge direction, then along it, per iteration — flattening texture and noise while edges and flowing detail survive. Much cheaper than a full 2D bilateral and calmer on video. The abstraction base of the toon look (follow with Posterize and Line Art). Steered by the `field` input (Image Flow Field or any velocity field) or an internal estimate when unwired. `Spatial σ` is the smoothing reach in px, `Range σ` how different colors must be to count as an edge (lower preserves more), `Across scale` shrinks the across-edge reach to protect edges harder.
space
param:sigma_s=pixels
gotcha
sigma_s is the spatial reach in pixels of each 1D pass; across_scale multiplies it only for the across-edge (gradient-axis) pass, not the along-edge (tangent) pass.
gotcha
field unwired computes its own orientation field internally from the source each evaluation; smooth only affects that internal estimate and is ignored while field is wired.
gotcha
Each iteration runs one across-edge pass then one along-edge pass in that fixed order; iterations (1..4) roughly multiply the cost.
gotcha
Both the spatial/range weighting and the range-distance comparison operate on premultiplied RGBA, so a soft edge is smoothed by its composited color, not its stored straight color.
Parameters
Name
Type
Default
Iterations
iterations
scalar
1 … 4
2
Spatial σ
sigma_s
scalar
0.5 … 10
4
Range σ
sigma_r
scalar
0.01 … 1
0.1
Across scale
across_scale
scalar
0.1 … 2
1
Internal smooth
smooth
scalar
0 … 32
4
Opacity
opacity
scalar
0 … 1
1
Sockets
Direction
Name
Type
input*
image
image
image
input
Field
field
image
outputprimary
out
image
Flow Blur
flow-blur
Smear the image along a flow field's streamlines (line integral convolution) — the painterly Van Gogh blur, and the standard way to SEE a field (wire noise into the image input). With `field` unwired the node derives flow from the image itself (structure tensor at `Internal smooth`); wire an Image Flow Field, Perlin curl, Spline Flow Field, or a sim's velocity aux to steer it. `Length` is the total ± smear distance (canvas-width fraction), `Samples` the quality per side. `Tangent` mode follows edge orientation regardless of direction; `Velocity` mode follows a directed field, smearing further where it's faster.
space
param:length=canvas01
gotcha
length is the total canvas-width-fraction smear distance split across both walk directions; step per sample = length/samples.
gotcha
field unwired: derives an internal structure-tensor field from the image itself (1px pre-blur, smooth param); wiring field ignores smooth entirely.
gotcha
mode=tangent walks the sign-coherent, direction-agnostic tangent; mode=velocity treats the field RG as a directed velocity, so smear length scales with local speed.
gotcha
Averages samples in premultiplied color and un-premultiplies on write, avoiding the darkened-fringe bug of straight-alpha averaging at soft edges.
Parameters
Name
Type
Default
Length
length
scalar
0 … 1
0.06
Samples
samples
scalar
1 … 64
16
Mode
mode
enum
"tangent"
tangent · velocity
Falloff
falloff
enum
"gauss"
gauss · box
Internal smooth
smooth
scalar
0 … 32
4
Opacity
opacity
scalar
0 … 1
1
Sockets
Direction
Name
Type
input*
image
image
image
input
Field
field
image
outputprimary
out
image
Flow Obstacle
flow-obstacle
Make a velocity field respect a shape: wire a field (Perlin Noise curl / Spline Flow Field) and an obstacle mask (any spline or shape coerces in), and flow deflects around the silhouette instead of passing through it. `deflect` redirects flow to slide along the boundary (and stalls it inside); `block` just damps flow by coverage for a dead-water stop. `radius` sets how far out the boundary's influence reaches — blur the mask upstream for an even softer approach. Chain several obstacles in series for multiple shapes.
space
param:radius=canvas01
gotcha
radius sets the finite-difference tap distance (canvas-width fraction, y-tap scaled by aspect) that mints a soft shell around the obstacle mask.
gotcha
mode=deflect removes the velocity component pointing into the shell and damps flow deep inside (coverage above ~0.5); mode=block just damps by coverage everywhere.
gotcha
Coverage is a 5-tap weighted average ((2*center + N+S+E+W)/6), not a true SDF falloff, so a hard mask still gets a soft shell from the taps alone.
gotcha
obstacle unwired: falls back to sampling the field texture itself as a dummy and forces strength to 0, i.e. a pure pass-through.
Parameters
Name
Type
Default
Mode
mode
enum
"deflect"
deflect · block
Radius
radius
scalar
0.002 … 0.2
0.03
Strength
strength
scalar
0 … 1
1
Sockets
Direction
Name
Type
input*
field
field
image
input*
obstacle
obstacle
mask
outputprimary
out
image
GLSL Expression
glsl-expressionpolymorphic
Write the body of a GLSL fragment shader and run it as one fullscreen pass — the per-pixel counterpart to Point Expression. Read wired images with texture(u_a, v_uv) (u_b–u_d), the clock with u_time/u_frame, and canvas size with u_res; write fragColor with straight alpha. Top-level function and struct definitions are hoisted above main() (or wrap them in // functions … // body). Declare tunables as one-line // comments and hit Sync to mint controls that the template exposes by name: // ch("k", 0.5, 0, 1) → uniform float k (slider); // toggle("on", true) → uniform bool on (pill); // pick("mode", "a", "b") → uniform int mode plus const int mode_a=0, mode_b=1 (2–3-way pill / dropdown); // color("tint", "#ff8800") → uniform vec4 tint (straight alpha, swatch); // ramp("ink", "#000000", "#ffffff") → vec4 ink(float t) (gradient editor, seeded by the hex list); // curve("falloff", 1, 0) → float falloff(float x) (float-curve editor, seeded by the y list). Sync is add-only (rows keep their tuned value — tune with set_param by channel NAME); scalar/toggle/color/ramp channels are also wireable inputs (scalar/scalar/vec4/color_ramp). Names can't start with u_. A compile error still renders passthrough/transparent — the WebGL info log is on get_shader_errors / get_graph (shaderError), and once in the console.
reads
time
gotcha
The cache only busts on the clock when u_time or u_frame appears literally in the source text; time-driven behavior reached only through a channel value won't invalidate the cache.
gotcha
Channel names may not contain a double underscore (GLSL reserves __identifiers) even if they'd otherwise pass the u_-prefix rule.
gotcha
Image inputs occupy texture units 0-3; ramp/curve channels bind LUTs starting at unit 4, capped at 12 ramp/curve channels per node (extras sample black).
gotcha
resolveInputs adds a wireable socket named in:<channel id> (not the channel's display name) for scalar/toggle/color/ramp channels.
gotcha
Top-level function and struct definitions are hoisted above main(); if auto-hoist misses a helper, wrap it in // functions … // body.
Parameters
Name
Type
Default
Channels
inputs
expr_inputs
[]
Shader
expression
string
"// Body of main(), plus optional helpers above it.\n// Top-level function / struct definitions are hoisted out of main()\n// (or wrap them in // functions … // body). Read inputs with\n// texture(u_a, v_uv) (u_b..u_d), the clock with u_time, canvas size\n// with u_res. Declare tunables as comments, hit Sync, then read them\n// by name:\n// // ch(\"amount\", 0.5, 0, 1) float amount\n// // toggle(\"invert\", false) bool invert\n// // pick(\"mode\", \"soft\", \"hard\") int mode (mode_soft, mode_hard)\n// // color(\"tint\", \"#ff8800\") vec4 tint\n// // ramp(\"ink\", \"#000000\", \"#ffffff\") vec4 ink(float t)\n// // curve(\"falloff\", 1, 0) float falloff(float x)\n// Write fragColor (straight alpha).\nvec4 a = texture(u_a, v_uv);\nfragColor = a;"
On error
on_error
enum
"passthrough"
passthrough · transparent
Sockets
Direction
Name
Type
input
a
a
image
input
b
b
image
input
c
c
image
input
d
d
image
outputprimary
out
image
Grain
grain
Procedural film grain with separate luminance and chromatic channels. Works as a stand-alone grain source (no input → grain on 50% gray) or as a one-shot composite over an input image with a choice of mix modes. Animate Seed (e.g. wire Scene Time in via a Math expression) for moving grain.
space
param:scale=pixels
gotcha
scale is grain-cell size in pixels at render resolution and does not scale with output size; 1 = finest, one independent sample per pixel.
gotcha
No image wired: renders grain alone on neutral 50% gray and ignores mix_mode/mix entirely, doubling as a standalone grain source.
gotcha
Every mix_mode treats grain as a layer centered at 0.5 + grain/2, so 0 grain is always identity regardless of which mode is chosen.
gotcha
luminance grain applies one value to R/G/B (brightness only, no hue shift); chromatic grain hashes each channel independently for colored speckle.
Detect up to two hands in an incoming image using MediaPipe HandLandmarker. Primary output is the hand skeleton as a spline (21 landmarks wired into 21 bones per hand). Aux outputs expose left/right wrist positions as vec2; toggling Show fingers adds per-finger tip vec2s (thumb / index / middle / ring / pinky on each side). Detection is throttled via `detect_fps` and the output is exponentially smoothed so downstream motion stays fluid between detect calls.
space
out,aux:left,aux:right=uv01
flags
unstable
gotcha
aux/out landmark positions are per-axis image-normalized (uv01), not width-isotropic canvas01, so a non-square input image skews the skeleton and finger positions.
gotcha
Detection throttles to detect_fps; between detect calls the node re-smooths the last-known landmarks every eval, keeping motion fluid at low detect_fps.
gotcha
A hand that exits frame keeps emitting its last smoothed skeleton (latched) instead of vanishing; a side never yet seen defaults vec2/points aux to (0.5,0.5).
gotcha
enabled=false freezes detection but keeps re-emitting the last latched, smoothed output, so the composed scene holds while paused.
gotcha
finger_output_mode swaps the aux socket set: vec2/point add ten per-side-finger sockets each; points adds one combined fingers points socket instead.
gotcha
flip_handedness (default true) swaps MediaPipe's person-perspective left/right label, since a mirrored front-facing webcam reports it backwards.
Parameters
Name
Type
Default
Enabled
enabled
boolean
true
Model
model
enum
"lite"
lite · full
Max hands
max_hands
enum
"1"
1 · 2
Confidence
confidence
scalar
0 … 1
0.5
Input size
input_size
scalar
128 … 1024
192
Detect rate (fps)
detect_fps
scalar
1 … 60
8
Smoothing
smoothing
scalar
0 … 0.99
0.5
Flip handedness
flip_handedness
boolean
true
Finger output
finger_output_mode
enum
"off"
off · vec2 · point · points
Sockets
Direction
Name
Type
input*
image
image
image
outputprimary
out
spline
outputaux
left
vec2
outputaux
right
vec2
Image Flow Field
image-flow-field
Estimate the flow of an image: per-pixel edge orientation (smoothed structure tensor) encoded as a field image — tangent direction in RG (velocity-field convention, so Advect Image/Points and Displace consume it directly) and anisotropy/coherence in B (0 = flat region, 1 = strong directed edge). The steering input for painterly nodes (Flow Blur, and the rest of the program as it lands): compute the field once, drive many consumers. `Pre-blur` gates pixel noise out of the gradient; `Smooth` sets the tensor-blur scale — larger values give longer, more coherent stroke directions. The `coherence` aux exposes B as a mask for driving anything (scatter density, thresholds…). Visualize the field by wiring it plus a noise image into Flow Blur. Don't matte or mask a field image — matte the consumer's output.
space
param:pre_blur,param:smooth=pixels
flags
no-mask
gotcha
pre_blur and smooth are Gaussian sigma in pixels at render resolution (radius = ceil(3σ), capped at 32 taps, a no-op below σ≈0.3px).
gotcha
RG encodes a π-periodic unit tangent (velocity-field convention, Y-down): t and −t are the same orientation; the producer picks the tx>0 representative.
gotcha
Gradients are computed on coverage-weighted luminance (lum × alpha), so a shape on transparency encodes its silhouette's orientation, not the background's.
gotcha
An unwired or non-image source returns a neutral field (zero tangent, coherence 0) rather than skipping the node.
gotcha
coherence is the B channel, (λ1−λ2)/(λ1+λ2) in [0,1]; any plain velocity image fed to an orientation consumer decodes coherence as 0 (flat).
Parameters
Name
Type
Default
Pre-blur
pre_blur
scalar
0 … 8
1
Smooth
smooth
scalar
0 … 32
4
Sockets
Direction
Name
Type
input*
source
source
image
outputprimary
out
image
outputaux
coherence
mask
Keyer
keyer
Keys pixels transparent by luminance (luma key), RGB similarity to a key color (color key), chroma-plane similarity (chroma key — the green-screen mode, brightness-independent), or similarity to a drawn color selection (sample mode — select the node and scrub across the canvas to sample the colors to remove). Softness feathers the matte edge, Spill Suppression desaturates key-color bleed on kept pixels, and Invert swaps keep/key. The matte is also available as a mask aux output.
gotcha
threshold only applies in mode=luma; key_color, tolerance, and spill apply only in color/chroma/sample modes.
gotcha
softness feathers symmetrically around threshold in mode=luma, but only outward past tolerance in the other modes.
gotcha
In mode=sample, the despill reference (used for spill) is the mean of the sampled colors, not key_color.
gotcha
sample_colors is a hidden list scrubbed from the canvas via the node's overlay; empty list keys nothing, capped at 64 colors.
Parameters
Name
Type
Default
Mode
mode
enum
"luma"
luma · color · chroma · sample
Threshold
threshold
scalar
0 … 1
0.5
Key Color
key_color
color
"#00ff00"
Tolerance
tolerance
scalar
0 … 1
0.2
Softness
softness
scalar
0 … 1
0.1
Spill Suppression
spill
scalar
0 … 1
0
Invert
invert
boolean
false
Sockets
Direction
Name
Type
input*
image
image
image
outputprimary
out
image
outputaux
matte
mask
Kuwahara
kuwahara
Painterly smoothing: each pixel pools the least-varying sectors of its neighborhood, flattening texture into paint-like facets while edges stay crisp. `Anisotropic` (default) stretches the facets into strokes along the local flow — steered by the `field` input (Image Flow Field, or any velocity field), or by an internal estimate when unwired — and is the temporally stable choice for video. `Generalized` keeps round isotropic facets. `Radius` is the brush size (cost grows with its square); `Sharpness`/`Hardness` set how crisply the winning facet dominates; `Anisotropy` scales how strongly flow coherence elongates strokes, with `Min coherence` forcing elongation where the field reports none (e.g. plain velocity fields).
space
param:radius=pixels
gotcha
radius is in pixels at render resolution and does not scale with output size; the ellipse major half-axis caps at 48px (MAX_EXTENT) regardless of anisotropy.
gotcha
anisotropy and min_coherence only apply in mode=anisotropic; generalized mode uses isotropic sectors and ignores the field entirely.
gotcha
field unwired computes an internal structure-tensor field from the source using the smooth param; smooth is ignored once field is wired.
gotcha
Sector means/variances accumulate in premultiplied color and un-premultiply on write, matching the convolve/boundary.ts convention.
Parameters
Name
Type
Default
Radius
radius
scalar
1 … 32
6
Mode
mode
enum
"anisotropic"
anisotropic · generalized
Sharpness
sharpness
scalar
1 … 16
8
Hardness
hardness
scalar
0.1 … 100
8
Anisotropy
anisotropy
scalar
0 … 2
1
Min coherence
min_coherence
scalar
0 … 1
0
Internal smooth
smooth
scalar
0 … 32
4
Opacity
opacity
scalar
0 … 1
1
Sockets
Direction
Name
Type
input*
image
image
image
input
Field
field
image
outputprimary
out
image
Lens Flare
lens-flare
Lens flare: chromatic ghosts + halo ring + anamorphic streak. Outputs the FLARE LAYER ONLY (transparent background) — composite back over the source with a Merge (additive) so you can pre-blur / tint between if you want.
ghost_dispersal, chromatic_aberration, halo_width, and streak_length are UV-fraction offsets in raw v_uv space (uv01), not aspect-corrected.
gotcha
Ghosts, halo, and streak all render at half the source resolution before the full-res composite; threshold/soft_knee affect all three via one shared bright-pass buffer.
gotcha
streak is skipped entirely (rendered blank) when streak_strength or streak_length is 0, instead of computing a zero-length blur.
gotcha
num_ghosts is rounded and clamped to 0..8 in JS; the shader loop itself hard-caps at 8 ghosts regardless of the param value.
Parameters
Name
Type
Default
Threshold
threshold
scalar
0 … 2
0.8
Soft Knee
soft_knee
scalar
0 … 1
0.4
Intensity
intensity
scalar
0 … 5
1
Tint
tint
color
"#ffffff"
Ghosts
num_ghosts
scalar
0 … 8
4
Ghost Dispersal
ghost_dispersal
scalar
0 … 1
0.4
Chromatic
chromatic_aberration
scalar
0 … 0.1
0.015
Halo Width
halo_width
scalar
0 … 1
0.5
Halo Intensity
halo_intensity
scalar
0 … 2
1
Streak Strength
streak_strength
scalar
0 … 2
0.6
Streak Length
streak_length
scalar
0 … 1
0.2
Streak Axis
streak_axis
enum
"horizontal"
horizontal · vertical · diagonal
Sockets
Direction
Name
Type
input*
image
image
image
outputprimary
out
image
Line Art
line-art
Extract stylized ink lines (XDoG): a soft-thresholded difference-of-Gaussians that sweeps from clean line art (low `Softness`) through charcoal tone (high). With `Flow` on the measurement runs across the image's flow and integrates along it (FDoG), consolidating broken contours into coherent hand-drawn strokes — visibly calmer on video than plain edge detection. Output is ink on transparency, ready to Merge over a Kuwahara / Flow Bilateral base (the painterly and toon stacks). `Size` is the line scale, `Threshold` how strong an edge must be, `Sharpen` the tone contrast. The optional `paper` mask modulates the threshold per-pixel — wire noise for hatching/charcoal texture. A wired universal mask mattes the ink.
space
param:size,param:flow_length=pixels
gotcha
size (line scale, sigma) and flow_length are pixels at render resolution and do not scale with output size; each Gaussian sums at most 24 taps per side.
gotcha
flow=true runs FDoG (across-flow measurement integrated along the tangent streamline); flow=false runs isotropic XDoG via two separable Gaussian blurs.
gotcha
flow_length and smooth only apply when flow is true; smooth drives the internal structure-tensor field and is ignored once field is wired.
gotcha
paper perturbs the threshold epsilon per-pixel, scaled by paper_strength; unwired paper leaves the threshold unmodified.
Parameters
Name
Type
Default
Flow
flow
boolean
true
Size
size
scalar
0.5 … 8
1.4
Contrast (k)
contrast
scalar
1.2 … 3
1.6
Sharpen
sharpen
scalar
1 … 50
20
Threshold
threshold
scalar
0 … 1
0.5
Softness
softness
scalar
0.01 … 2
0.3
Flow length
flow_length
scalar
0 … 16
4
Paper strength
paper_strength
scalar
0 … 1
0.5
Ink
color
color
"#000000"
Invert
invert
boolean
false
Internal smooth
smooth
scalar
0 … 32
4
Opacity
opacity
scalar
0 … 1
1
Sockets
Direction
Name
Type
input*
image
image
image
input
Field
field
image
input
Paper
paper
mask
outputprimary
out
image
Liquid Glass
liquid-glass
Apple-style refractive liquid glass over a backdrop. Wire the image behind the glass into the backdrop input; a built-in rounded-rect/superellipse panel (optionally smooth-merged with a second shape) refracts, disperses, and glares over it. Wire an SDF into `shape` for any analytic shape — circles, booleans, smooth-union blobs, or splines via SDF Spline.
posX/posY/width/height and bPosX/bPosY/bWidth/bHeight are per-axis UV fractions (uv01): X scales by canvas width, Y independently by height, not aspect-corrected.
gotcha
cornerRadius and bCornerRadius are 0..1 fractions of the shape's own min(halfWidth, halfHeight) in px, not an absolute distance.
gotcha
thickness, strength, blur, mergeRadius, and shapeSmooth are raw pixels at render resolution and do not scale with output size.
gotcha
shapeMode=replace makes a wired shape SDF fully replace the built-in shape(s); shapeMode=merge smooth-unions it in via mergeRadius.
gotcha
Texture-backed SDFs (e.g. SDF From Image) auto-smooth their normal at 3px to avoid a moire/faceted look, unless shapeSmooth overrides it.
gotcha
blurEdge (Frost) blends the whole glass toward the blurred backdrop; off, it blends sharp-to-blurred only from center to edge across thickness.
gotcha
The shader recompiles whenever the wired shape SDF's structural topology changes; animating existing SDF params only rebinds uniforms.
Parameters
Name
Type
Default
Shape
shapeType
enum
"rounded-rect"
rounded-rect · circle
Position X
posX
scalar
0 … 1
0.5
Position Y
posY
scalar
0 … 1
0.5
Width
width
scalar
0 … 1
0.4
Height
height
scalar
0 … 1
0.26
Corner Radius
cornerRadius
scalar
0 … 1
0.6
Roundness (squircle)
roundness
scalar
2 … 12
5
Second Shape
secondShape
boolean
false
Shape B
bShapeType
enum
"circle"
circle · rounded-rect
B Position X
bPosX
scalar
0 … 1
0.66
B Position Y
bPosY
scalar
0 … 1
0.5
B Width
bWidth
scalar
0 … 1
0.16
B Height
bHeight
scalar
0 … 1
0.16
B Corner Radius
bCornerRadius
scalar
0 … 1
1
B Roundness
bRoundness
scalar
2 … 12
5
Merge
mergeRadius
scalar
0 … 400
60
Shape Input
shapeMode
enum
"replace"
replace · merge
Shape Smoothing (px)
shapeSmooth
scalar
0 … 16
0
Edge Thickness
thickness
scalar
1 … 400
80
Refraction (IOR)
ior
scalar
1 … 2.5
1.5
Refraction Strength
strength
scalar
0 … 400
60
Dispersion
dispersion
scalar
0 … 3
0.4
Backdrop Blur (px)
blur
scalar
0 … 60
8
Frost (blur center)
blurEdge
boolean
false
Tint
tint
color
"#ffffff"
Tint Opacity
tintOpacity
scalar
0 … 1
0
Fresnel
fresnelFactor
scalar
0 … 3
1
Fresnel Range
fresnelRange
scalar
1 … 500
120
Fresnel Hardness
fresnelHardness
scalar
-1 … 1
0
Glare
glareFactor
scalar
0 … 2
0.6
Glare Angle
glareAngle
scalar
-180 … 180
45
Glare Range
glareRange
scalar
1 … 500
120
Glare Hardness
glareHardness
scalar
-1 … 1
0
Glare Convergence
glareConvergence
scalar
0 … 1
0.4
Glare Opposite
glareOppositeFactor
scalar
0 … 1
0.5
Opacity
opacity
scalar
0 … 1
1
Sockets
Direction
Name
Type
input*
backdrop
image
image
input
shape (SDF)
shape
sdf
outputprimary
out
image
Merge
mergepolymorphic
Blends a base image with one or more layer images. Every image input carries its own mask input underneath — the matte for that layer (multiplies its per-pixel coverage, like a track matte). In AI recipes: `layers: [{mode, opacity, maskInvert?}, …]` *replaces* the default stack (N entries → N layers, new ids — not appended onto lyr-initial). Later set_param patches keep ids by index so existing wires never dangle. Wire inputs ordinally — layer1, layer2, … (mask1, mask2, … for the mattes) — they resolve to the real per-layer sockets, growing the stack when layerN points past the end.
flags
no-mask
gotcha
mode=mix is a legacy alias identical to normal (same blend formula); it only exists so old saves keep loading.
gotcha
A layer's enabled=false skips it from compositing but keeps its socket, so the wire stays connected without contributing.
gotcha
maskInvert only inverts a layer that has a mask actually wired; on an unmasked layer it is a no-op, not a full blank.
gotcha
Composites in straight (non-premultiplied) alpha via source-over; every RGB blend formula (multiply, screen, etc.) operates on straight color.
Detect objects in an incoming image using MediaPipe. Emits bounding-box rectangles (spline) and per-detection centers (points). IDs persist across frames via IoU matching.
space
out,aux:positions=uv01
writes
attr:scale
flags
unstable
gotcha
Box and point coordinates are raw per-axis width/height fractions (uv01), not aspect-corrected canvas01, so geometry skews on non-square canvases.
gotcha
Detection only actually runs at detect_fps; frames in between reuse the last frame's tracked boxes unchanged.
gotcha
IDs persist via greedy IoU matching (threshold 0.3) within the same category only; unmatched previous boxes are dropped and new ones get fresh IDs.
gotcha
Switching model reloads asynchronously: the old model keeps running until the new one is ready, and output is empty while no detector is loaded (including the first-run download).
gotcha
retimeable: false — Time Offset cannot rewind this node; it always passes through the current frame's live detections unshifted.
Parameters
Name
Type
Default
Model
model
enum
"lite0"
lite0 · lite2
Confidence
confidence
scalar
0 … 1
0.4
Max results
max_results
scalar
1 … 25
5
Input size
input_size
scalar
128 … 1024
320
Detect rate (fps)
detect_fps
scalar
1 … 60
15
Sockets
Direction
Name
Type
input*
image
image
image
outputprimary
out
spline
outputaux
positions
points
Pixelate
pixelate
Mosaic the image into blocks, sampling each block's center. Square or circular cells; aspect stretches the grid for non-square mosaics.
space
param:size=pixels
gotcha
size is in pixels of the source texture (u_res), not canvas-relative; the same value looks larger on a lower-resolution render target.
gotcha
aspect stretches only the cell width (u_cell.x = size*aspect); cell height stays size, so aspect only widens/narrows tiles, it does not scale them uniformly.
gotcha
shape=circle sets RGBA to 0 (not just alpha) outside the inscribed disc, so the corners become true transparent-black holes rather than a softened edge.
Parameters
Name
Type
Default
Block size (px)
size
scalar
1 … 256
16
Cell shape
shape
enum
"square"
square · circle
Aspect
aspect
scalar
0.25 … 4
1
Opacity
opacity
scalar
0 … 1
1
Sockets
Direction
Name
Type
input*
image
image
image
outputprimary
out
image
Polar Coords
polar-coords
Map an image between rectangular and polar coordinates. Rect ⇒ Polar wraps the source around the center (kaleidoscope / tunnel looks); Polar ⇒ Rect unrolls a circular source into a strip. Center, rotation, and radial scale set the pivot and orientation.
space
param:center_x,param:center_y=uv01
gotcha
center_x/center_y are per-axis UV fractions (not aspect-corrected); radius = length(v_uv − center) mixes both axes with no aspect term, so circles skew into ellipses on non-square canvases.
gotcha
mode=rect-to-polar reads the source as (angle=x·2π, radius=y) and paints the resulting disc; mode=polar-to-rect is the inverse unroll, not a simple parameter swap.
gotcha
wrap=transparent leaves out-of-range samples as alpha 0; clamp clamps UV to [0,1]; mirror reflects with abs(fract(uv*0.5)*2−1), a full mirror-tile rather than one flip.
gotcha
rotation is in radians and offsets the angle axis directly, independent of scale_radius.
Parameters
Name
Type
Default
Mode
mode
enum
"rect-to-polar"
rect-to-polar · polar-to-rect
Center X
center_x
scalar
-1 … 2
0.5
Center Y
center_y
scalar
-1 … 2
0.5
Rotation (rad)
rotation
scalar
-3.141592653589793 … 3.141592653589793
0
Radius scale
scale_radius
scalar
0 … 4
1
Edge
wrap
enum
"clamp"
transparent · clamp · mirror
Sockets
Direction
Name
Type
input*
image
image
image
outputprimary
out
image
Posterize
posterize
Quantize the image to a small number of tonal levels for a flat, screen-print / cel-shaded look. Per-channel (rgb) or brightness-only (luma, preserves hue).
gotcha
quant() snaps to L evenly spaced values inclusive of both endpoints, in de-gamma'd space (pow(x, 1/gamma)) then re-gamma'd back on output.
gotcha
channels=luma quantizes brightness only and rescales rgb by ql/l to preserve hue; near-black pixels (l<1e-4) rescale to pure black instead of dividing by ~0.
gotcha
levels is floored to at least 2 and gamma to at least 0.001 even if a wired value goes lower.
gotcha
alpha passes through unchanged; channels=rgb quantizes r/g/b independently, which can shift hue near band edges unlike luma mode.
Parameters
Name
Type
Default
Levels
levels
scalar
2 … 32
6
Channels
channels
enum
"rgb"
rgb · luma
Gamma
gamma
scalar
0.2 … 4
1
Opacity
opacity
scalar
0 … 1
1
Sockets
Direction
Name
Type
input*
image
image
image
outputprimary
out
image
Reaction Diffusion
reaction-diffusionpolymorphic
Gray-Scott / FitzHugh-Nagumo reaction-diffusion patterns. Pick a preset, tune step count. Optional seed image sets the initial U/V fields (R → U, G → V); otherwise starts from a central splat.
reads
time
flags
simulation, unstable
gotcha
Seed image only reads the R channel as brightness × seed_intensity to set V (U = 1−V); it is not a literal R→U, G→V split despite the description.
gotcha
Steps only run while ctx.playing is true; scrubbing or pausing freezes the sim unless drive_by_scene_time is on, which instead steps when the wired time input advances past its last value.
gotcha
Resets (re-seed from the seed image or the central splat) whenever scene time drops back near 0 after being nonzero, i.e. a loop, or on the first eval.
gotcha
resolution (0.1-1) scales the internal sim texture relative to canvas size, floored at 4px per side; output upsamples the V channel to full canvas with linear filtering.
gotcha
preset != custom ignores feed/kill/alpha/beta/gamma entirely; only preset=custom reads those raw model params.
Tone curves — a combined RGB curve plus individual R / G / B curves.
gotcha
The master (combined RGB) curve applies to all three channels first, then each per-channel R/G/B curve is applied on top of that result.
gotcha
Alpha passes through unmodified; only RGB is curved.
gotcha
Each channel's curve bakes to a 256-entry monotone-cubic LUT that is then linearly interpolated per lookup, not evaluated exactly per input value.
Parameters
Name
Type
Default
Curves
curves
curves
(complex)
Sockets
Direction
Name
Type
input*
image
image
image
outputprimary
out
image
Segment Anything
segment-anything
Segment images locally via Transformers.js. Dots mode: select the node and click the canvas to drop dots on what you want — each dot adds another object (SlimSAM); outputs a cutout + selection mask. Auto modes need no points and output an evolving multicolor segment map: Semantic (SegFormer classes, inherently stable colors), Panoptic (DETR instances, overlap-matched across frames), Auto Grid (SAM point grid, slow but class-agnostic) — set Levels for the segment count, and use the grayscale id-map aux with a Color Ramp for custom palettes. For animated inputs, Bake runs the model over an in/out frame range and caches a mask per frame; Free Bake clears it.
gotcha
ML inference never runs in compute(): dots run SlimSAM on click, Bake runs it over inFrame..outFrame — compute only picks the cached mask for ctx.frame and uploads it.
gotcha
mode=dots outputs a cutout + selection mask; mode=semantic/panoptic/grid colorize per-slot IDs instead, with `levels` normalizing the id map for Color Ramp.
gotcha
Baked masks are session-only: dots/inFrame/outFrame/feather/threshold save with the project, the decoded bitmaps do not — reopening a project needs one re-bake.
gotcha
Before any dot is placed (or before the first baked frame decodes), the node passes the source through with an all-white mask so downstream wiring isn't blocked.
gotcha
In offline export, an undecoded baked frame blocks via pushMediaSettle for frame accuracy; realtime playback instead shows the previous mask texture for a frame.
gotcha
Index masks upload with NEAREST filtering and no color-space conversion — slot IDs are exact integers, not colors to interpolate.
Parameters
Name
Type
Default
Mode
mode
enum
"dots"
dots · semantic · panoptic · grid
Levels
levels
scalar
2 … 32
6
Feather
feather
scalar
0 … 1
0
Threshold
threshold
scalar
0.1 … 0.9
0.5
Sockets
Direction
Name
Type
input*
image
image
image
outputprimary
out
image
outputaux
mask
mask
outputaux
mask_image
image
Sharpen
sharpen
Sharpen an image with one of four kernel shapes. Box/diamond/cross are Laplacian-style (crisp); unsharp uses a Gaussian reference for softer falloff.
gotcha
All four algorithms are single-pass 3×3 taps at the native pixel grid (u_invRes = 1/width, 1/height) — they do not scale with a wired kernel or radius param.
gotcha
algorithm=box/diamond/cross are Laplacian sharpens (amount scales neighbor subtraction); unsharp uses Gaussian-weighted 3×3 weights instead, for softer falloff and less ringing.
gotcha
algorithm=cross taps only the four diagonal neighbors, so it sharpens diagonal edges while leaving axis-aligned edges untouched.
gotcha
Output RGB is not clamped and can overshoot [0,1] on high-contrast edges; alpha always passes through untouched.
Parameters
Name
Type
Default
Algorithm
algorithm
enum
"box"
box · diamond · cross · unsharp
Amount
amount
scalar
0 … 5
1
Sockets
Direction
Name
Type
input*
image
image
image
outputprimary
out
image
Stipple
stipple
Re-renders the input as a field of dots whose size and density follow input darkness. Grid (jittered halftone-ish), Screen (stochastic), Packed (organic relaxed-Poisson), and Packed-Flow (persistent dots with fade-in/out + position lerp for animated inputs) modes share the same edge-noise and colorization layer. Dots are either a flat color or sample the image's color at each dot center (pointillism color transfer); the optional `color` input substitutes a different image for that sampling.
space
param:maxMatchDistance=uv01
gotcha
dotMinSize/dotMaxSize scale radius as a fraction of the grid cell's pixel size (mix(min,max,density) × cellPx × 0.5), not absolute pixels.
gotcha
mode=grid rejects a cell below `threshold` density; mode=screen instead accepts each cell stochastically with probability density^densityCurve.
gotcha
Packed relax only runs on the GPU (WebGPU compute) when pointCount ≥ 6000 and relaxIterations > 0; otherwise, or on WebGPU failure, it runs on the CPU.
gotcha
relaxIterations=0 skips relaxation entirely: packed/packed-flow show the raw density-weighted scatter with no Poisson-like spacing.
gotcha
Only packed-flow keeps dot identity across rebakes, matching new targets to old dots within maxMatchDistance; unmatched dots fade out, new ones fade in.
gotcha
colorSource=image samples the `color` input at each dot's center when wired, else falls back to sampling the main image input.
gotcha
GPU relax is asynchronous: the first frame after a change shows an unrelaxed seed set; offline export waits for the settled result before capturing.
gotcha
samplerResolution sets the density field's downsample size as a multiple of the grid cell count, trading bake speed for input detail.
Parameters
Name
Type
Default
Mode
mode
enum
"grid"
grid · screen · packed · packed-flow
Grid Density
gridSize
scalar
10 … 500
120
Density Curve
densityCurve
scalar
0.1 … 5
1
Invert
invert
boolean
false
Threshold
threshold
scalar
0 … 1
0.02
Point Count
pointCount
scalar
100 … 20000
4000
Relax Iterations
relaxIterations
scalar
0 … 20
4
Relax Strength
relaxStrength
scalar
0 … 3
1
Seed
packedSeed
scalar
0 … 9999
1
Sampler Resolution
samplerResolution
scalar
0.5 … 8
2
Fade In (s)
fadeInTime
scalar
0.01 … 5
0.4
Fade Out (s)
fadeOutTime
scalar
0.01 … 5
0.6
Flow Speed
flowSpeed
scalar
0.1 … 30
4
Max Match Dist
maxMatchDistance
scalar
0 … 1
0.08
Dot Min Size
dotMinSize
scalar
0 … 3
0.1
Dot Max Size
dotMaxSize
scalar
0 … 3
1.4
Jitter Min
jitterMin
scalar
0 … 1
0
Jitter Max
jitterMax
scalar
0 … 1
0.6
Jitter Bias
jitterBias
scalar
0.1 … 5
1
Edge Noise Scale
noiseScale
scalar
0.1 … 40
6
Edge Roughness
noiseRoughness
scalar
0 … 1
0.4
Edge Strength
noiseStrength
scalar
0 … 1
0.18
Color Source
colorSource
enum
"flat"
flat · image
Dot Color
dotColor
color
"#4ca134"
Background
backgroundColor
color
"#ece5d0"
Background Alpha
backgroundAlpha
scalar
0 … 1
1
Sockets
Direction
Name
Type
input*
image
image
image
input
color
color
image
outputprimary
out
image
Swift-Hohenberg
swift-hohenbergpolymorphic
Swift–Hohenberg pattern formation (labyrinthine stripes, hexagons, spots). Pick a preset, tune wavelength; optional seed image sets the initial signed field.
space
param:wavelength=canvas01
reads
time
flags
simulation, unstable
gotcha
wavelength is the pattern period as a canvas-width fraction; the sim grid is sized so one period is ~8 texels at resolution=0.5 (resolution scales texels-per-wave, not canvas size).
gotcha
Steps run while ctx.playing or (ctx.offline and time advanced); pause/scrub freezes unless drive_by_scene_time, which steps when the wired time input increases.
gotcha
Resets the field (seed image or hash noise) on first eval or when scene time wraps back near 0.
Seed image stores (luma-0.5)*2*seed_intensity as the signed field; unwired, init is hash noise in ±seed_intensity.
gotcha
Output is 0.5+0.5*tanh(u*contrast) of the signed field; quadratic=0 gives stripes/rolls, nonzero quadratic breaks ±u symmetry into hexagons/spots.
gotcha
periodic=true (default) sets REPEAT wrap so patterns tile; periodic=false clamps and tends to pin rolls to the frame edges.
Parameters
Name
Type
Default
Preset
preset
enum
"hexagons"
labyrinth · hexagons · spots · custom
Epsilon
epsilon
scalar
0 … 1.5
0.3
Quadratic
quadratic
scalar
-2 … 2
0.35
Cubic
cubic
scalar
0 … 4
1
Time step
dt
scalar
0.001 … 0.2
0.03
Wavelength
wavelength
scalar
0.01 … 0.25
0.05
Steps / frame
steps_per_frame
scalar
1 … 80
16
Resolution
resolution
scalar
0.1 … 1
0.5
Seed intensity
seed_intensity
scalar
0 … 1
0.15
Init seed
init_seed
scalar
0 … 1000
0
Contrast
contrast
scalar
0.05 … 2
1
Periodic
periodic
boolean
true
Drive by scene time
drive_by_scene_time
boolean
false
Sockets
Direction
Name
Type
input
seed
seed
image
outputprimary
out
image
Threshold
threshold
Binary luminance threshold — pixels brighter than the threshold become white, darker become black. Softness widens the transition into a feathered smoothstep edge; Invert swaps the two sides. Uses Rec. 709 luma weighting.
gotcha
softness is the full width of the smoothstep transition window, centered on threshold (threshold ± softness/2), not a multiplier on it.
gotcha
Output alpha is passed through unchanged from the source; only RGB is replaced by the grayscale threshold result (t,t,t).
gotcha
Luminance is Rec. 709 luma of the source RGB, ignoring source alpha.
Parameters
Name
Type
Default
Threshold
threshold
scalar
0 … 1
0.5
Softness
softness
scalar
0 … 1
0
Invert
invert
boolean
false
Sockets
Direction
Name
Type
input*
image
image
image
outputprimary
out
image
Trails
trailspolymorphic
Temporal trails — each echo is a faded copy of an earlier frame (opacity only, no color mix). Primary is the current frame over the echoes; the trail aux is echoes only. Feedback: continuous motion trail. Ring: stepped stop-motion echoes. Velocity: directional motion blur along a vector or UV field. History advances only while the timeline plays, and wipes on skip-to-start, loop wrap, or hitting Play.
space
param:velocity_x,param:velocity_y=uv01
reads
time
flags
simulation, unstable
gotcha
History only advances while the timeline is playing or exporting; paused param tweaks or repeated same-time evals freeze it instead of decaying further.
gotcha
The history buffer wipes on skip-to-start / scene-time wrap back near 0, and on every Play (resume from pause); pause itself does not wipe.
gotcha
mode=ring captures a new echo only every step_frames active frames; between captures the primary output freezes on the last captured composite.
gotcha
mode=velocity always re-captures the raw current input as history (not the blurred output), so the directional blur doesn't compound frame over frame.
gotcha
velocity_x/y are the full backward-sweep UV offset at the last tap, not a per-tap or per-frame step; wiring vel_uv overrides them entirely.
gotcha
vel_uv decodes its RG channels from [0,1] into a [-1,1] per-pixel UV vector, used as the local velocity in place of velocity_x/y.
gotcha
decay compounds per captured frame in feedback/ring (echo alpha keeps fading each capture) but falls off per tap within one eval in velocity mode.
gotcha
The trail aux is echoes only, with no current frame composited on top, and is only rendered when actually wired downstream.
Parameters
Name
Type
Default
Mode
mode
enum
"feedback"
feedback · ring · velocity
Decay
decay
scalar
0 … 1
0.92
Step (frames)
step_frames
scalar
1 … 30
2
Velocity X
velocity_x
scalar
-0.5 … 0.5
0
Velocity Y
velocity_y
scalar
-0.5 … 0.5
0
Taps
taps
scalar
1 … 64
8
Sockets
Direction
Name
Type
input*
image
image
image
outputprimary
out
image
outputaux
trail
image
Vector Field
vector-fieldpolymorphic
Turn an image or SDF into a signed-RG velocity field (the encoding Advect Points / Advect Image / Displace / Point Expression already read). Attract pulls toward the feature (inward on an SDF, toward bright on an image); repel pushes away; orbit circulates; isoline follows level sets at unit speed. `radius` is falloff-from-surface on an SDF, and the finite-difference tap on an image (blur a mask upstream for a volumetric well — a hard edge only has gradient at the rim). Chain an upstream field through the optional `field` input to sum flows. Don't matte a field image — matte the consumer.
space
in:source=raster|canvas01 param:radius=canvas01
flags
no-mask
gotcha
radius/falloff is a canvas01 width-relative, aspect-corrected distance in both modes; in SDF mode only, turning off aspect_correct makes it a uv01 per-axis fraction instead.
gotcha
mode=isoline uses a hard band (metric < radius) instead of the smoothstep falloff the other three modes use.
gotcha
field additively sums an already RG-encoded velocity field; chain upstream fields here instead of matting the output image.
gotcha
On an image source, radius also sets the finite-difference tap, so a hard binary mask only has gradient at its rim — blur it upstream for a volumetric well.
gotcha
Attract pulls inward on an SDF (−∇d) but toward brighter pixels on an image (+∇luma); repel/orbit rotate or invert that same gradient.
Parameters
Name
Type
Default
Mode
mode
enum
"attract"
attract · repel · orbit · isoline
Strength
strength
scalar
-2 … 2
0.5
Radius
radius
scalar
0.001 … 1
0.15
Invert
invert
boolean
false
Aspect Correct
aspect_correct
boolean
true
Sockets
Direction
Name
Type
input
Source
source
image
input
Field (add)
field
image
outputprimary
out
image
Utilities
Frame
frame
Wraps an image in a fixed-size element for Auto Layout. Width and height are in layout units (1/1000 of the canvas's smaller dimension); fit controls how the image fills the rect.
flags
no-mask
gotcha
width/height are layout units: 1 unit = 1/1000 of min(canvas width, canvas height) in px, isotropic on both axes (unlike canvas01's width-only scaling).
gotcha
With no image wired, both the element primary and the aux image fall back to an empty zero-size element instead of erroring.
gotcha
preferredSizing is hug on both axes, so a layout slot set to hug takes exactly the authored width x height; fit only matters once the slot differs from that size.
Parameters
Name
Type
Default
Width (units)
width
scalar
1 … 4000
300
Height (units)
height
scalar
1 … 4000
300
Fit
fit
enum
"cover"
cover · contain · stretch
Sockets
Direction
Name
Type
input*
image
image
image
outputprimary
out
element
outputaux
image
image
Image Trace
image-trace
Trace a raster into splines. Potrace fits a binary silhouette; VTracer (WASM) clusters color regions. Fill color is stamped on each subpath as color + driver.
mode=potrace traces a binary silhouette (darker-than-threshold, after invert); mode=vtracer clusters color (clustering=color) or thresholds (clustering=bw).
gotcha
max_size, turdsize, and filter_speckle are in the downsampled trace pixel grid, not canvas pixels, so raising output resolution does not add detail unless max_size is raised too.
gotcha
Until the chosen WASM backend finishes loading, the node emits an empty spline and re-evaluates via a pipeline-bump once ready; offline export waits on the in-flight trace.
gotcha
attrs.color is 0–1 RGB from the SVG fill; driver is Rec.709 luminance of that fill. Cutout holes become separate subpaths (evenodd is not preserved on the spline wire).
Parameters
Name
Type
Default
Engine
mode
enum
"potrace"
Potrace · VTracer
Max size (px)
max_size
scalar
32 … 2048
512
Invert
invert
boolean
false
Threshold
threshold
scalar
0 … 1
0.5
Suppress specks
turdsize
scalar
0 … 100
2
Corner (α max)
alphamax
scalar
0 … 1.334
1
Curve tolerance
opttolerance
scalar
0 … 1
0.2
Turn policy
turnpolicy
enum
"minority"
minority · majority · black · white · left · right