Skip to content

Compositor

The Compositor is Plinken’s GPU-accelerated layer system for building visual scenes. Composite cameras, images, video, text overlays, shaders, 3D scenes, and volumetric effects into a single output — for live streaming, video production, or offline rendering.

Layers (z-ordered)
↓ compile (on scene change)
VideoGraph (DAG nodes)
↓ render (per frame, wgpu)
Output → IOSurface / CVPixelBuffer
WHEP / RTMP / SRT / Recording

The compositor uses a DAG-based renderer (DagRenderer) that compiles layers into a GPU node graph. Changes to layers trigger recompilation; rendering executes the graph every frame.

ModeDescription
LiveReal-time rendering with optional frame skipping
OfflineFull-quality render at arbitrary resolution

The canvas defines the output frame dimensions and frame rate.

PropertyTypeDefaultDescription
Widthu321920Output width in pixels
Heightu321080Output height in pixels
Frame Ratef6430.0Output frames per second (24, 25, 29.97, 30)
-- Set canvas resolution and frame rate
pl.cmd("scene:set-canvas", {
width = 1920,
height = 1080,
frame_rate = 30
})

Layers are the building blocks of a composition. Each layer has a source, transform, opacity, blend mode, and visibility/lock state. Layers render in z-order (bottom to top).

SourceType KeyDescription
CameracameraLive webcam feed by device index
Remote Cameraremote_cameraiOS device camera via RTP
RTMP Ingestrtmp_ingestExternal RTMP encoder (DJI, OBS)
ImageimageStatic image (PNG, JPG, WebP)
VideovideoVideo file with looping and position
ColorcolorSolid RGBA color fill
TexttextStyled text with font, size, and color
CaptioncaptionTimeline-driven caption with karaoke highlighting
Timeline Tracktimeline_trackVideo from a timeline video track
Scene Capturescene_captureNested scene composition
ParticipantparticipantWebRTC remote guest video
ShadershaderISF shader effect with parameters
Custom Shadercustom_shaderUser-written ISF shader
BrowserbrowserWeb page (URL-based)
ActionactionTriggered overlay (action buttons 0–15)
3D Scenescene3dGLB model or panoramic image
Gaussian Splatsplat3D Gaussian Splat (.ply)
LightslightsStage lighting overlay
SDF ShapesdfProcedural shape (circle, rect, polygon, star)
Volume FXvolume_fx3D volumetric effect (fire, smoke, fog)
Particle Volumeparticle_volumeGPU particle system
NDIndiNDI® network video input
Desktop Capturedesktop_captureScreen capture
Window Capturewindow_captureWindow capture
MaskType KeyDescription
Rectanglemask_rectSDF rectangle with corner radius and feather
Ellipsemask_ellipseSDF ellipse with feather
Gradientmask_gradientLinear gradient (start/end points)
Beziermask_bezierClosed bezier path (up to 16 control points)

Masks use grayscale as alpha: white = visible, black = hidden. Toggle Invert to flip.

PropertyTypeRangeDefaultDescription
xf320.0–1.00.0Horizontal position (normalized)
yf320.0–1.00.0Vertical position (normalized)
scale_xf320.0–10.01.0Horizontal scale
scale_yf320.0–10.01.0Vertical scale
rotationf32-360–3600.0Rotation in degrees
anchor_xf320.0–1.00.5Pivot point X
anchor_yf320.0–1.00.5Pivot point Y
content_zoomf320.1–10.01.0Zoom inside the frame
content_xf32-1.0–1.00.0Pan X inside the frame
content_yf32-1.0–1.00.0Pan Y inside the frame
PropertyTypeDefaultDescription
opacityf321.0Layer opacity (0.0–1.0)
corner_radiusf320.0Rounded corners
layer_featherf320.0Edge feathering (soft edges)
visiblebooltrueWhether the layer renders
lockedboolfalsePrevents selection and editing
is_groupboolfalseFolder layer — children render, source ignored
is_maskboolfalseUse as grayscale mask for parent
PropertyTypeDefaultDescription
glow_radiusf320.0Outer glow radius
glow_color[f32; 4][1,1,1,0]Glow color (RGBA)
outline_widthf320.0Outline/stroke width
outline_color[f32; 4][1,1,1,0]Outline color (RGBA)
PropertyTypeDefaultDescription
shadow_offset_xf320.0Shadow X offset
shadow_offset_yf320.0Shadow Y offset
shadow_blurf320.0Shadow blur radius
shadow_color[f32; 4][0,0,0,0]Shadow color (RGBA)
ModeDescription
NormalStandard alpha blending
AddAdditive (brightens)
MultiplyMultiply (darkens)
ScreenScreen (lightens)
OverlayOverlay (contrast)
AverageWeighted average of all inputs

Blend modes are implemented as wgpu fragment shaders supporting 2-way and 4-way blending.

The GPU pipeline provides node-based video processing:

EffectDescription
BrightnessAdjust brightness (value multiplier)
ContrastAdjust contrast
SaturationAdjust color saturation
InvertInvert colors
GrayscaleConvert to grayscale

Effects are composable — chain multiple effects in a VideoGraph:

-- Apply brightness and contrast via video grade
pl.cmd("scene:set-grade", {
brightness = 1.2,
contrast = 1.1,
saturation = 0.9
})
Command IDDescription
slot:addAdd a new layer
slot:deleteRemove a layer
slot:renameRename a layer
slot:move-upMove layer forward (toward viewer)
slot:move-downMove layer backward
slot:reorderMove layer to specific z-position
slot:toggle-visibleShow/hide layer
slot:toggle-lockedLock/unlock layer
slot:set-sourceChange layer source
slot:set-transformUpdate transform properties
slot:set-opacitySet layer opacity
slot:set-blend-modeSet blend mode
slot:set-automation-trackLink automation track
slot:set-record-trackLink recording track
slot:set-text-trackLink text track
scene:set-canvasSet canvas resolution/fps
scene:set-gradeSet video color grading
-- Add a camera layer
pl.cmd("slot:add", {
name = "Main Camera",
source = { type = "camera", device_index = 0 }
})
-- Add an image overlay
pl.cmd("slot:add", {
name = "Logo",
source = { type = "image", path = "/path/to/logo.png" }
})
-- Update layer transform
pl.cmd("slot:set-transform", {
index = 0,
x = 0.75, y = 0.05,
scale_x = 0.2, scale_y = 0.2
})
-- Set blend mode
pl.cmd("slot:set-blend-mode", {
index = 1,
mode = "screen"
})
-- Toggle layer visibility
pl.cmd("slot:toggle-visible", { index = 0 })
-- Rename a layer
pl.cmd("slot:rename", { index = 0, name = "Hero Camera" })

3D Scene layers use an orbital camera with spherical coordinates.

PropertyTypeDefaultDescription
Orbit Target (X/Y/Z)vec3(0, 0.5, 0)Center of orbit
Distancef323.5Camera distance from target
Azimuthf32Horizontal orbit angle
Elevationf3215°Vertical orbit angle
Focal Lengthf3245°Field of view
Focus Distancef320Depth of field distance
Look Target (X/Y/Z)vec3(0, 0, 0)Independent look direction
Follow Deadzonef320Deadzone before tracking

Procedural shapes rendered via Signed Distance Fields:

ShapeIndexDescription
Circle0Perfect circle
Rectangle1Rectangle
Rounded Rect2Rectangle with corner radius
Ring3Ring (hollow circle)
Polygon4Regular n-gon (3–12 sides)
Star5Star with alternating radii

All compositor properties can be automated via MIDI CC on a linked automation track.

CCParameter
0Position X
1Position Y
2Scale X
3Scale Y
4Rotation
5Anchor X
6Anchor Y
7Content Zoom
8Content X
9Content Y
10Opacity
CCParameter
20Mask X
21Mask Y
22Mask Width
23Mask Height
24Corner Radius
25Feather
26Radius X
27Radius Y
CCParameter
40Orbit Target X
41Orbit Target Y
42Orbit Target Z
43Distance
44Azimuth
45Elevation
46Focal Length
47Focus Distance
48Look Target X
49Look Target Y
50Look Target Z
51Follow Deadzone

The compositor supports multiple scenes. Each scene has its own layer stack, resolution, and frame rate. Switch between scenes for different camera angles, overlays, or visual themes.

-- Switch to a scene
pl.cmd("streaming:switch-scene", { scene_id = 2 })
-- Go live (push preview to program)
pl.cmd("streaming:go-live")