Skip to content

GPU Effects

GPU effects are Arkestra’s built-in hardware-accelerated effects. Unlike ISF shaders — which run a fragment program per pixel — GPU effects use Metal compute pipelines, multi-pass rendering, frame ring buffers, codec encode/decode sessions, or other heavier GPU work that isn’t practical inside an ISF shader. That extra power comes with a proportionally higher GPU and CPU cost, so use them with awareness when stacking multiple effects on busy tracks.

You find GPU effects in the Add Content browser under the GPU Effects category. They load into a chain slot just like any ISF effect.

The list is split into three groups:

GroupWhat’s in it
LayersGenerators and compositions — simulations such as Fluid Solver and Wave Sim, signal generators such as Oscilloscope, and poster layouts such as Reactive Poster and Type Repeater
EffectsEffects that process the input, sub-grouped into Glitch, Time, Color and Trace
UtilitiesRouting tools such as Track Texture

GPU Effects list in the Add Content browser


Produces real codec-level glitch artifacts by running video through an H.264 VideoToolbox encode/decode pipeline and suppressing I-frames (keyframes). Without fresh reference frames, the decoder’s motion compensation applies old motion vectors to stale pixel data, causing the characteristic smear and pixel-bleeding look of datamosh.

Why it’s heavy: maintains two VT compression sessions (motion encoder + pixel encoder) and a decompression session simultaneously. Each frame involves H.264 encode, NAL manipulation, and async decode on the hardware video codec. Texture bridging between OpenGL and CVPixelBuffer via IOSurface adds per-frame work.

ParameterWhat it does
QualityH.264 encoder quality (low = more compression artifacts)
BloomReplays the same P-frame through the decoder N extra times, accumulating smear on each pass
RefreshMomentary — forces a fresh I-frame into the decoder, resetting the reference frame
MoshToggle freeze/smear. Off = shows live input; on = feeds decoder output back
Motion SourceOptional secondary track to donate motion vectors instead of the primary input
Swap MotionToggle between primary and Motion Source for motion vectors

Displaces rows (or columns) of the output so each row samples from a different point in a frame history buffer. Rows at the top sample recent frames; rows at the bottom sample older ones, creating time-smearing and panoramic stretching effects.

Why it’s heavy: maintains a ring buffer of up to 60 frames as a texture2d_array, with Metal compute doing the per-row time-offset compositing every frame.

ParameterWhat it does
Buffer DepthHow many frames of history to store (2–60 frames)
SpeedRate at which the time offset animates across the image
DirectionVertical (rows displaced) or horizontal (columns displaced)

Detects edges in the input using a Sobel shader, runs a GPU marching-squares pass to extract contour segments, then tracks and smooths those contours as persistent glowing paths rendered with Metal. Supports two simultaneous threshold levels for layered fine/bold edges.

Why it’s heavy: each frame involves an ISF edge detection render, a Metal compute kernel (marching squares), CPU path engine updates, and a Metal line renderer composited back to an OpenGL texture. The CPU trace pipeline runs on a background thread and is pipelined with the render to avoid blocking, but the GPU work still adds up on high-resolution output.

ParameterWhat it does
Threshold 1 / 2Edge detection sensitivity for the two trace levels
Fade SecondOpacity of the second (fainter) trace level; set to 0 to run only one level
SmoothingEMA smoothing applied to path positions over time
Max PathsMaximum number of simultaneous active contour paths (1–128)
Decay RateHow quickly inactive paths fade out
RDP EpsilonRamer–Douglas–Peucker simplification — higher values remove more intermediate points
Points Per PathMax resampled points stored per path in the GPU buffer (4–64)
Glow IntensityBrightness multiplier for the rendered lines
Glow ColorBase HSV color for traced paths
Pixel MixBlend between Glow Color and the source pixel color at each path’s centroid
CompositeRender paths over black, or composite over the source image

Rebuilds the frame as a modular editorial poster. The output is split into columns of unequal width, each cut into stacked rows, and every resulting slot is filled with one of four things: video, a word of type, a flat palette colour, or a symbol from the bundled CoolShapes set. Video is aspect-filled into its slot; type and symbols are stretched to bleed against all four edges.

Video and type each come in pairs — two texture sources and two word pools with their own typefaces — so one poster can hold a headline against a caption, or two feeds against each other.

Why it’s heavy: it rasterises type and symbols into a coverage atlas with CoreText and CoreGraphics whenever the text, fonts or symbol set change. That work runs off the render thread, so a change costs a frame or two of stale typography rather than a dropped frame. The atlas is split into independent sections — each text pool and the symbols rasterise and upload on their own, so editing one text field re-uploads two tile rows instead of the whole atlas. The per-frame compositing pass itself is cheap, and its output is double-buffered so a frame is composited without the render thread ever blocking on the GPU or copying the result.

ParameterWhat it does
ColumnsNumber of vertical columns (2–12)
LayoutColumn-width profile: Even, Ramp, Bulge, Alternate, Cascade, Scatter
RowsHow aggressively columns split into stacked rows (1–4 rows per column)
PulseSpreads every column and row away from its base size along a fixed per-slot direction — the whole grid breathes at once
SurgeCollapses the grid toward one seeded focal column, and one focal row inside every column. Where Pulse breathes all over, Surge makes the poster lunge at a single panel
GlitchDigital corruption. Tears each slot’s own content along seeded horizontal bands; on video the colour channels split on the torn bands, and a torn type slot may mis-set and print the wrong word from its pool. 0 is clean
Glitch RateHow often the glitch reshuffles, as a beat division locked to the project clock. Slow divisions hold a broken frame; fast ones stutter it. Only shown once Glitch is up
SeedReshuffles row splits, pulse directions, the focal slot and automatic content assignment
GapGutter between slots, filled with the background colour

Pulse, Surge and Glitch are the parameters built for audio. They stack, and they read completely differently: map Pulse to a sustained band for constant motion, Surge to a transient so a kick throws the poster onto one panel, and Glitch to whatever you want to shred in time — because it is seeded per slot and stepped on the beat, a held value corrupts a fixed set of slots while a swept one walks the tearing around the grid. Surge past about 0.6 squeezes the non-focal columns down to slivers, which is either the point or too far depending on the track.

ParameterWhat it does
Texture 1What fills Texture 1 slots. Defaults to the chain input; can be pointed at another track, a chain or embedded chain, or a single effect’s output
Texture 2A second, independent source with the same choices. Also defaults to the chain input, so the pair goes together until you point one somewhere else
Texture BlendShare of automatic texture slots drawing from Texture 2 rather than Texture 1. 0 = all source 1, 1 = all source 2
ColorizeRecolours video into the poster palette — Off, Mono, Duotone, or Threshold
Colorize AmountBlends the recoloured result back towards the untouched video
Colorize ContrastRamp steepness for Mono and Duotone; the cut point for Threshold

Colorize pulls its colours from the poster itself: each texture slot maps its shadows to the Ink colour and its highlights to the same seeded palette pick that backs the type slots around it. Change Seed or the palette and the video follows. Amount and Contrast only appear once a mode is picked.

ParameterWhat it does
Text 1First word pool. Split on whitespace — each word fills one type slot, cycling when there are more slots than words (16 words max)
Font 1Typeface for Text 1. One of 16 poster faces, from Helvetica Condensed Black through Impact to Didot
Text 2Second word pool, with its own typeface and its own 16-word limit
Font 2Typeface for Text 2
Text BlendShare of automatic type slots drawing from Text 2 rather than Text 1. 0 = all pool 1, 1 = all pool 2
UppercaseUppercases every word in both pools before rasterising
Vertical TypeProportion of type slots rotated 90°
SymbolsWhich CoolShapes family to draw from: All, Sparkles, Crosses, Circles, Dots, Geometric, Petals
Fit SymbolsSymbols stretch to fill their slot like type does. Tick this to opt a mark back out and keep its own proportions inside the slot

Each pool walks its own words, so neither runs out early because the other filled more slots. Empty one of the two and every slot falls through to the pool that still has words.

The four mix sliders are relative weights that decide what fills a slot. They choose the category; the two blend sliders then choose which half of each pair the slot lands on. A source with nothing to show falls back first to its partner, then to a flat colour.

ParameterWhat it does
Texture MixWeight for slots filled with video, from either texture source
Text MixWeight for slots filled with a word, from either pool
Color MixWeight for slots filled with a flat palette swatch
Symbol MixWeight for slots filled with a symbol
ParameterWhat it does
BackgroundPoster background, also shown in the gutters
InkColour of the type and symbols
InvertShare of slots printed flipped
Color A / B / CPalette used for colour slots and for the paper behind type. A slot never picks a paper too close in luminance to the ink

Invert flips a slot whatever it holds. Type and symbols swap their ink and paper, so they reverse out light-on-dark instead of printing dark-on-light. It is one seeded draw per slot, so at 0.35 roughly a third of the poster prints the other way round and the rest stays put — which is the point, since a flipped panel only reads as flipped next to one that isn’t.

A flip only ever exchanges two palette colours. It never negates one. On a red / white / black poster you get black-on-white becoming white-on-black, or red-on-black becoming black-on-red — the poster never picks up a colour you didn’t give it.

Because the draw is seeded, a static value picks a fixed set of slots and Seed reshuffles which ones. Map it to sweep slots in and out instead.

Video slots flip inside the Colorize ramp, running it the other way so an inverted video slot lands in the same two palette colours as the flipped type around it. Mono has no colour pair to exchange, so it flips its grey ramp instead. With Colorize off, Invert leaves video alone — raw video has no ink and paper to swap, and negating it would be exactly the out-of-palette result Invert exists to avoid.


Fills the frame with repeated poster type. The frame is cut into rows (and optionally columns), and every cell prints one word stretched edge to edge. Rows scroll continuously, a noise field bows and stretches them, and each cell is seeded on its own, so which cells are empty, outlined, or from the second word pool varies across the grid. It draws its own image on a flat background — it doesn’t use the chain input.

Why it’s heavy: it rasterises the words into a type atlas with CoreText whenever the text or fonts change. That runs off the render thread, so an edit costs a frame or two of stale type rather than a dropped frame. The per-frame compositing pass is cheap and double-buffered.

ParameterWhat it does
Text 1First word pool. Split on whitespace; each cell prints one word (32 words max)
Font 1Typeface for Text 1. One of 16 poster faces, from Helvetica Condensed through Impact to Didot
Text 2Second word pool, with its own 32-word limit
Font 2Typeface for Text 2
Text BlendShare of cells drawing from Text 2 rather than Text 1
UppercaseUppercases every word in both pools
ParameterWhat it does
RowsNumber of repeated rows (1–40)
ColumnsNumber of columns (1–12). 1 repeats vertically only
DensityShare of cells that stay filled. Lower it to empty cells out of the grid
WaveOrganic vertical warp — rows bow, stretch and compact instead of sliding as one sheet. 0 is a straight grid
Wave FreqGrain of the wave: low gives a few broad swells, high gives choppy row-to-row turbulence
SurgeSwells one seeded row (and column) while compacting the rest. The grid keeps its overall size, so only the proportions move
ScrollVertical scroll speed. Positive scrolls down, negative up, 0 holds still

Wave and Surge pair well with audio: map Wave to a sustained band for steady breathing and Surge to a transient so a kick makes one row lunge.

ParameterWhat it does
OutlineShare of cells printed as outlines instead of filled. 0 is all filled, 1 all outline
Outline WidthStroke weight, the same in every cell whatever its type size — from a hairline to a heavy rule
SeedReshuffles which cells are empty, outlined, and which word they print
BackgroundBackground colour
InkType colour

Sorts pixels along rows, columns, or paths around the centre of the frame, rearranging image content into the characteristic streaks of glitch art pixel sorting. Mode decides how each line is broken into sorted runs, and Amount drives whichever mode is selected.

Why it’s heavy: every pixel in the frame takes part in a single GPU sort each frame, plus scan passes to find the run boundaries.

ParameterWhat it does
ModeHow lines are broken into sorted runs — see below
AmountDrives the selected mode; 0 is closest to untouched, 1 is fully sorted
Sort ByWhich channel to sort on: Luminance, Hue, Saturation, Value, Red, Green, Blue, Alpha
SeedVaries the pattern in Random mode; animate it to make the pattern evolve
DirectionThe path each sort runs along — see below
ReverseFlips the sort order within every run
MirrorHorizontal and Vertical only: splits each row or column at the centre so both halves sort outward from the middle, mirroring the result. With Reverse off or on, the streaks run out from the centre or in towards it
IntensityBlend between sorted and original output
ModeWhat it does
FullSorts each whole line; Amount is ignored
Reveal DarkSorts the darkest Amount fraction, leaving bright pixels pinned in place
Reveal BrightSorts the brightest Amount fraction, leaving dark pixels pinned
RandomRandom-length runs; Amount controls how long they get, Seed varies the pattern
EdgesRuns break wherever the channel gradient exceeds Amount, so sorting follows image detail
MeltAmount blends smoothly from untouched to fully sorted instead of switching runs on and off
DirectionWhat it does
HorizontalSorts along rows
VerticalSorts along columns
ZoomSorts outward along rays from the centre, so streaks run along the line joining each pixel to the middle of the frame, converging from every direction at once — a perspective tunnel, close to a feedback zoom. Reverse flips which end of the ray the sorted pixels pile up at
RadialSorts around circles centred on the frame, so streaks smear tangentially and the image appears to rotate about the centre. Each circle is mirrored across the horizontal axis so the sorted runs meet cleanly instead of leaving a hard seam

A full GPU Navier-Stokes fluid simulation, ported from Evan Wallace’s WebGL Water. Maintains advection, diffusion, and divergence fields in separate Metal compute passes. Can output height/normal maps, velocity flow fields, or displacement data for use in 3D chains.

Why it’s heavy: runs multiple full-screen compute passes per frame (advect, diffuse, pressure solve, gradient subtract). Output resolution directly scales the cost.

Output modes include Height (height + normals as RGBA), Velocity (RGB flow field for particle systems), and Displace (normal.xz + height encoded for 3D displacement chains).


Records a window of frames into a ring buffer and loops them. With Loop off, the buffer rolls continuously (nothing is frozen). Triggering Grab captures the current window and starts looping it. Loop length can be set freely or locked to a beat division.

Why it’s heavy: allocates and manages a VVBuffer ring buffer sized by loop length × frame resolution.

ParameterWhat it does
LengthLoop length in frames (free mode; hidden when BPM sync is on)
BPM SyncLock loop length to the selected beat division
LoopToggle between live passthrough and frozen loop playback
GrabMomentary — record a fresh window and begin looping

Freezes the current frame for a set number of ticks, then snaps to live input. Creates rhythmic strobe and stutter effects. Can be synced to BPM with a beat division for musically locked stuttering.

ParameterWhat it does
Hold LengthHow long to freeze (1–30 frames; free mode only)
ProbabilityChance of actually triggering a freeze on each interval (0–1)
BPM SyncLock stutter timing to the selected beat division

Runs the input through H.264 encode/decode at extremely low quality settings, introducing heavy macroblocking, banding, and compression artifacts. Unlike Datamosh, keyframes are never dropped — this is pure codec degradation. An optional double-encode pass applies the compression twice for more extreme destruction.

Why it’s heavy: like Datamosh, it maintains VideoToolbox encode/decode sessions. Lower quality settings can push the codec harder.


A shallow water wave simulation (discrete spring PDE) that responds to a virtual sphere moving through the surface. Can output height/normal data, a velocity flow field for particle systems, or displacement data for 3D tracks. Physics are computed each frame in Metal compute.


Renders parametric oscillator and Lissajous curves as a texture using a Metal line renderer. Useful as a generator-style insert at the start of a chain to feed subsequent effects with geometric waveforms.


Remaps individual RGBA output channels from selectable input sources. Equivalent to TouchDesigner’s Reorder TOP. Uses a Metal compute shader for per-pixel channel routing.


Color grades the image through a 3D lookup table loaded from a .cube file — the same format Resolve, Premiere, and most LUT packs export. The table is uploaded as a 3D Metal texture and sampled with hardware trilinear interpolation, so even large LUTs cost the same per frame.

Arkestra ships with a set of starter looks (Warm Film, Cool Night, Bleach Bypass, Blockbuster, Faded Matte, Neon Nights, Mono Contrast, Vivid Pop), copied into your LUT folder on first launch.

ParameterWhat it does
LUTWhich lookup table to apply. None passes the image through untouched
AmountBlends between the original and graded image

The LUT parameter is a regular select parameter, so it can be mapped to MIDI, an LFO, or a sequencer to switch looks during a set.

Arkestra scans two folders:

  • ~/Documents/Arkestra/luts — the default folder. Drop .cube files here.
  • An additional folder of your choice — set it in Settings → General → LUT Folders, useful for pointing at an existing LUT pack library. Subfolders are scanned too.

Both folders feed the same list. If two LUTs share a filename, the second one is suffixed with its parent folder name. Use Rescan in settings after adding files while Arkestra is running.

If a project references a LUT you don’t have, the name stays selected in the dropdown and the effect passes through until the file turns up again.


Compresses HDR (over-range, above-1.0) chain values into a displayable 0–1 range. Generators, feedback loops, and additive blends can produce values brighter than 1.0 that a normal display simply clips — drop a Tonemap at the end of an HDR chain to roll those highlights off smoothly instead of blowing them out.

Adding a Tonemap effect automatically promotes the upstream chain to 16-bit float (RGBA16F) rendering, so over-range values survive all the way to the tonemap node without any manual track setting. The output is always 8-bit, since the result is display-referred.

ParameterWhat it does
OperatorTone-mapping curve — ACES, Reinhard, Hable, or Clamp
ExposureExposure offset applied before tonemapping; the center position is neutral (0 EV), spanning roughly −4 to +4 EV
White PointLuminance level that maps to full white, on a 1–8 scale (used by Reinhard and Hable)
LinearizeLinearizes gamma-encoded input before tonemapping and re-encodes afterward

Routes another track’s render output (or 3D position texture) directly into the current chain. Enables cross-track texture routing and feedback-style setups without Syphon.


Overlays Vision framework tracking data — face landmarks, hand skeleton, or body pose — onto the input texture. Reads live tracking data from Arkestra’s Vision tracker each frame and renders the skeleton or mesh on top of any source.


Estimates how far away each part of the picture is, on your Mac’s Neural Engine, and outputs it as an image: near is white, far is black. It uses the same model as estimated depth, so Quality, Stabilize and the first-use model download work the same way, and the effect shows the same Model and Depth Rate rows. Until the model is ready, the input passes through unchanged.

ParameterWhat it does
OutputDepth outputs the grayscale depth map. Key keeps the input and fades it out with distance, so far areas become transparent
NearDepth that maps to white (fully kept). Lower it to push everything in front of that point to full white
FarDepth that maps to black (fully cut). Raise it to drop the background. With Near and Far close together you get a hard cut
InvertSwaps near and far

To cut a layer by depth, the simplest route is a mask in Depth mode. The effect is useful when you want depth as an image in the chain:

  • Key inside a chain: add Depth to the layer and set Output to Key, then raise Far until the background falls away.
  • Use depth as a mask elsewhere: put Depth on a track (or tap its output), then pick it as the source of a mask in Texture mode with Channel set to Luma. Threshold and Softness then shape the cut.

Depth updates on its own schedule (see Depth Rate), so on fast motion the depth can trail the picture slightly.


GPU effects can stack, but each one adds real workload. A few things to keep in mind:

  • Datamosh and Quality Crusher each maintain active VideoToolbox codec sessions. Running several simultaneously can saturate the hardware encoder/decoder.
  • Image Tracer runs a CPU trace pipeline concurrently — it’s pipelined to avoid stalls, but high path counts (Max Paths) and fine details (Threshold, low RDP Epsilon) increase CPU time.
  • Fluid Solver and Wave Sim scale with output resolution. Running them at 1080p+ on a busy scene is noticeably heavier than at 720p.
  • ISF effects by comparison are single-pass fragment shaders with minimal overhead — prefer them for simple colour or distortion work and reach for GPU effects when you specifically need the temporal or simulation behaviour they offer.