Skip to content

Shader clips

A shader clip runs a GLSL fragment shader on the Edit timeline, once for every frame. It's for the pictures a Lottie can't make: generative backgrounds, warping an image or video, outlines around a 3D model, glitches and light effects. You write the shader once, then drive it from the Clip panel with sliders, colours, images, videos and models.

A fragment shader is a small program that decides the colour of one pixel. The graphics card runs it for every pixel at once, which is why it can do things a keyframed layer can't.

Adding one

  • Media Bin ▸ Generators ▸ Shaders lists the starters. Drag one onto a video lane, or add it at the playhead. Rest the pointer on a row to see it move. A starter that works on a picture or a sound has nothing chosen yet, so the row and its preview fill in with pictures and a beat that come with Kitlig: a sunset lake for the lanes below, a night city as a second plate, depth maps for both, and a cut-out. Titles and animations sit over a dimmed picture so you can read them. None of this reaches a clip: on the timeline the shader uses what you choose.
  • Ask the Assistant: "add a slow gradient background" or "warp this image like water" (see Agents).
Starter What it does Needs
Gradient flow Two colours drifting through each other Nothing
Radial burst Rays from a point over transparent. Keyframe Amount to fire it Nothing
Grid pulse A glowing floor running to the horizon, over transparent Nothing
Liquid warp Bends a picture like water An image or video
Kaleidoscope Folds a picture into mirrored wedges An image or video
RGB glitch Slices a picture and splits its colours An image or video
Model outline A turning 3D model drawn as glowing edges A .glb

The rest sit in their own groups on the same shelf:

Group What's in it
Shaders: text Heat halo, Zoom smear, Velocity smear, Signal glitch, Chroma tear, Liquid chrome, Retro chrome, Star glint, Ink erode, Halftone bloom, Echo stack, Elastic stretch, Letter cascade, Print wobble, Fire text, Neon sign, Melt, Disintegrate, Hologram
Shaders: fire, space and weather Fire, Flame, Galaxy, Star warp, Nebula, Aurora, Lightning, Embers, Snowfall, Smoke, Light tunnel, Light leak, Burn through
Shaders: looks for footage VHS, Old film, Thermal, Comic ink, Print dots, Mosaic reveal, Pixel sort, Lens character, ASCII, Dither, Halftone
Shaders: lens Chromatic aberration, Lens flare: from highlights, Lens flare: point, Camera lens
Shaders: audio Spectrum bars, Circle visualizer, Waveform, Spectrogram, Beat pulse, Beat glitch, Bass bloom, Beat sparks, Sound meter
Shaders: analog and glitch VHS dropouts, Camcorder, CRT screen, Analog broadcast, Block glitch, Row tear, Heat haze
Shaders: grain and dirt Film grain: 35mm, Film grain: 16mm, Dirty film, Damaged print, Scan lines
Shaders: depth 2.5D camera move, Depth fog, Depth of field, Depth blur, Bokeh, Bokeh: bright lights, Bokeh: smooth lens, Depth mask, Depth composite: two plates, Depth composite: cutout, 3D model in a scene, Depth scan, Depth contours, Depth relight

Every colour and strength in them is a control in the Clip panel, and the numbers can all be keyframed.

A new clip is five seconds long, and you can trim it to any length. The shader keeps running for as long as the clip lasts.

Transform, opacity, blend mode, fades and clip keyframes all work on a shader clip as they do on footage. A shader that writes transparency lets the lanes below show through, so put it on an upper lane to use it as an overlay.

The Clip panel

Select the clip and open Clip. The Shader section shows one control for each input the shader has:

  • A Number or Whole number gets a field, plus a slider when it has a range. The player follows the slider as you drag it.
  • An On / off gets a checkbox.
  • A Colour gets a swatch.
  • A Point gets an X and a Y. Some points, like a flame's Position, also show as a handle on the player. See Placing things in the frame.
  • An Image or video gets a picker for your project's pictures, with Clamp edges, Repeat or Mirror for what happens past its edge, and Smooth or Pixelated for how it's sampled. A video also gets Start at and Loop. Without Loop its last frame holds.
  • A 3D model gets a picker for your project's .glb files. See 3D models.
  • A Text input gets the words, a font and its style. See Text effects.

If the shader has a problem, the section says what and on which line.

Animating inputs

Numbers, whole numbers and points take keyframes. Open Keyframes and they appear under a Shader group beside the clip's own position and opacity, with the same dope sheet, graph and easing.

Once an input has keys, a change in the Clip panel sets a key at the playhead rather than changing the whole input. With Auto-key on, any change does. A small diamond next to the field tells you the input is keyed, and clicking it opens the drawer.

Keys stay with the picture. Trim the head of a shader clip and the animation doesn't slide: the clip just starts later in it.

Text effects

A text effect reads your words from a Text input: up to 64 characters, in any of Kitlig's fonts, with Bold, Italic, alignment, Size, Tracking, a position and line spacing. A long title shrinks to stay inside the frame.

Most effects bring themselves in and out over their In and Out times, in seconds, and all of them sit over transparent so they can go on an upper lane. To time one by hand, set In and Out to 0 and keyframe its strength.

Using footage

The looks read Picture, which starts as Lanes below: whatever the tracks under the shader clip show at that moment, footage, titles, other shaders and all, already placed, faded and blended. Put a look on an upper lane over your edit and it works like an adjustment layer; trim it to the shots that should have the look. The player draws it over the live lanes, and the export feeds the shader the very frame it has just composited.

A texture can read a chosen image or video instead. Pick one in the Picture picker, and it's cropped to fill the frame. Both can be mixed in one shader: a look that reads the lanes below with a depth map from the Media Bin, for instance.

ASCII, Dither and Halftone

  • ASCII draws the picture in characters. Characters holds the set, darkest first, in any font, and a space makes a blank cell. Density (cell size) sets how fine it is. Turn on Picture colour for colour, or off for one Character colour on Background.
  • Dither uses a fixed pattern to decide which pixels tip over to the next tone. Set Dither size, Threshold, Exposure, Contrast, Pattern strength and Levels, and pick Dark and Light colours or keep Picture colour.
  • Halftone prints the picture in four inks at four screen angles. Set Dot size, Screen angle, Exposure, Contrast, Softness and every ink and the paper.

Grain and dirt

These need no picture. Put one on a lane above your footage and it lays over everything below, with no blend mode to set. Each has its own Amount or Grain, a size, a colour for its light and dark marks, and Frames a second, so grain can step like real film even on a 60 fps timeline. Dirty film adds dust, hairs, scratches and flicker, and Damaged print adds blotches, tramlines and a slipping frame line.

Depth

The depth effects read a Picture and a Depth map: a greyscale image or video where brightness is distance. Run a depth operation on a picture or a video (Depth Map ▸ Depth Anything for video) and the result is attached to its source, so choosing that source as Picture fills Depth map for you. With Picture left on Lanes below, pick the depth video yourself; it plays in step with the clip, so put the shader clip over the footage at the same start.

Depth Anything and most estimators draw near things bright, and Focus counts the same way: 1 is the nearest, 0 the farthest. If near things are dark in your map, turn on Near is dark. Depth maps are estimates, so edges can look soft or wrong where the map is. 2.5D camera move works best with small moves, because the picture has nothing behind what it shows.

Five of them blur by focus, all with a Focus you can keyframe for a rack focus and an In focus range around it:

  • Depth of field is the quick one: one blur amount, with brighter highlights.
  • Depth blur is a soft, even blur with Far blur and Near blur set apart, so a background can melt while the foreground only softens.
  • Bokeh is a lens: Aperture sets the size, Blades the shape (0 is round, 6 a hexagon) with a Blade rotation, Highlight glow and Highlight threshold make the lights bloom into the aperture's shape, and Rim pushes the brightness to the edge of each disc for the soap-bubble look. Near blur scales how much the foreground blurs against the background.

  • Bokeh: bright lights is for night streets, sun through leaves and anything with small bright points. Highlights take over their whole disc, crisp against a soft picture, the way they do through a real lens. Highlight strength sets how far they win (1 is a plain blur), Disc size the size, Disc edge how hard the discs are, and Blades the shape. It needs no depth map: Focus is then a line across the frame, with Focus line tilt, which also gives a tilt-shift look. Turn on Focus by depth map to focus by depth instead.

  • Bokeh: smooth lens is the clean one for footage: no noise and no holes, even on a large blur. Aperture sets how fast things leave focus and Largest blur caps how soft they get. Edge hold sets how firmly a subject keeps its outline against the background behind it (lower is firmer). A soft foreground still spreads over what it covers. It reacts to depth more smoothly than the others, so it forgives a rough depth map better.

Blurred things stay behind sharp ones: a face in focus never smears into the soft background behind it, and a blurred foreground spreads over what it covers. Dither trades a little grain for smoother discs.

Depth mask

Depth mask keeps a band of depth between Near edge and Far edge, feathered by Softness, and does one of three things with it (Output): cuts the picture out over transparent, so what is on the lanes below the shader clip shows through where the band isn't; draws the band as a white-on-black matte you can use as a mask elsewhere; or keeps the picture inside the band and fills everything else with Fill. Invert swaps band and rest, and Strength scales the mask. Keyframe the edges to reveal a scene plane by plane. For the cut-out, pick the clip itself as Picture rather than Lanes below: a hole cut into the lanes below would only show those same lanes through it.

Depth composites

Three presets put things into a shot by comparing depths, so a person in the plate walks in front of what you add and behind it as the depth says:

  • Depth composite: two plates takes two pictures that each have a depth map (Picture and Depth map, Plate B and Plate B depth map) and shows, for every pixel, whichever is nearer. Plate B can be centred and given a width (its height follows its own shape), and its depth shifted or scaled to sit where you want it in A's space; a Contact shadow darkens A just behind where B sits.
  • Depth composite: cutout takes one plate with depth and a flat picture (a cutout with alpha, a sign, a card) set at a single Depth in the scene, with Lean tilting its depth from bottom to top, plus centre, size, opacity and tint.
  • 3D model in a scene renders a .glb into the shot. Pick a Panorama (an equirectangular image) and the model is lit by it; Show the panorama as the sky also draws it behind the model, turned to the model's camera, with Sky exposure and Sky turn. Depth in the scene and Depth thickness place the model in the plate's depth so nearer things in the footage hide it, and Shadow drops a soft shadow under it. Turn off Hide behind nearer things for a plate without a depth map.

Lens

These work on the lanes below, so put one on an upper lane over your edit.

Chromatic aberration splits edges into a spectrum towards the corners, the way glass bends each colour by its own amount. Amount and Edge falloff set how much and how far out it starts, Centre moves the axis, and Sideways shift adds a plain offset for a misaligned look. The three colours run across the fringe, so the classic red and blue can become anything.

Lens flare: from highlights needs nothing placed. Whatever is bright in the picture throws ghosts and a halo through the centre of the frame, blooms and streaks, so the flare moves with the shot. Highlight threshold decides what counts as a light. The ghosts, halo, bloom and glare each have their own strength and colour, and Dirt and starburst breaks them up the way glass does, using a picture of your own if you choose one.

Lens flare: point is for a shot with no bright light to work from. Drag Source on the player, or keyframe it. With a depth map and Hide behind nearer things, the flare fades as the source passes behind something nearer than Source depth.

Camera lens is a whole lens in one clip, in the order the light meets it:

  • Distortion: Distortion bends the picture (positive is barrel, negative is pincushion), Distortion at the edges adds more towards the corners, and Fit to frame zooms just enough to hide the edges. Optical centre, Colour fringe and Vignette are here too.
  • Dirt on the glass: leave Dirt picture empty for built-in smears and specks, or pick your own. Dirt position, Dirt scale, Dirt rotation and Dirt blur place it. Dirt only shows where light reaches it, so Dirt lit by highlights makes it flare up near bright parts of the shot.
  • Aperture shape: Blades and Blade rotation shape the bokeh, Anamorphic squeeze makes it oval, and Cat eye at the edges cuts the discs towards the corners of the frame like a real lens barrel.
  • Depth: turn on Depth of field and give it a Depth map. Focus, In focus range, Aperture, Largest blur and Edge hold work as in Bokeh: smooth lens, and Highlight strength keeps the lights bright in the blur.

Without Depth of field the lens costs very little. With it, this is the heaviest shader on the shelf.

Placing things in the frame

Flame is one fire you direct. Select the clip and drag the handle on the player to place its base. With keys on Position, or with Auto-key on, each drag sets a key at the playhead, so you can pose a path by moving the playhead and pulling the handle.

  • Size, Width and Height shape it, and Distance pushes it back so it reads smaller.
  • Drag makes it lean behind its own motion, so a moving flame trails. Lean is a steady wind.
  • Gradient: core, Gradient: bright, Gradient: flame and Gradient: edge are its four colours.
  • Give it a Depth map (optional) and set Depth in the scene, and anything nearer than that covers it.

Note

The flame is drawn flat in the frame. Distance and the depth map make it sit in a scene, but it isn't a 3D object you can walk the camera around.

3D models

A model input renders your .glb on every frame, over transparent, and hands that picture to the shader. Your shader then treats it like any other texture, so it can outline it, warp it or light it. It reads the picture of the model and not its mesh, so a shader can't move the vertices.

The model sits on a camera that orbits its centre:

  • Turn and Tilt place the camera.
  • Distance is a multiple of the distance that just fits the model in the frame.
  • Lens is the field of view.
  • Spin turns the camera in degrees per second.
  • Play its animation plays the first animation in the file, with Start at and Loop. Without Loop the last pose holds.
  • Lit by picks a texture input holding an equirectangular panorama to light the model with (reflections included); otherwise a neutral studio room lights it. Exposure brightens or darkens the render and Light turn rotates the panorama around the model.

A shader also receives the model's depth as <name>Depth (1 nearest the camera, 0 farthest, over the model's own extent) and its camera as <name>View (yaw, pitch and field of view in radians), which is how the composite presets set a model among the things in a plate and draw a sky that matches its camera.

Note

Only .glb files can be used, and only the first animation in a file plays. The camera settings can't be keyframed yet, so use Spin for a turn.

The shader editor

Edit shader… opens the code beside a live preview, with a frame scrubber and play button. Below the preview is the list of Inputs. Add input makes a new one, and each row sets its name and type.

Nothing reaches the clip until it compiles. An error underlines its line and shows in the footer, Apply stays off, and the preview keeps showing the last version that worked. Press Ctrl+S to apply. Start from a preset… replaces the code and inputs with a starter, and nothing is lost until you apply it.

Writing a shader

Kitlig expects GLSL ES 3.00 with a mainImage function, the same shape as Shadertoy:

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
  vec2 uv = fragCoord / uResolution;
  float wave = 0.5 + 0.5 * sin(uv.x * 10.0 + uTime * speed);
  fragColor = vec4(tint * wave, 1.0);
}

fragCoord is the pixel, counted from the bottom left. fragColor is red, green, blue and alpha from 0 to 1, with the colour not multiplied by its alpha.

These are always there:

Name Type What it holds
uTime float Seconds into the shader
uResolution vec2 The frame in pixels
uFrame int Whole frames into the shader
uProgress float 0 at the clip start, 1 at its end
uDuration float The clip length in seconds
uFps float Frames per second

iTime, iResolution and iFrame work too, so most Shadertoy code pastes in. Code that uses Shadertoy's iChannel textures needs those swapped for your own inputs.

Don't declare your inputs. Add them in the editor and they arrive as uniforms with the same name:

Input In the shader
Number float
Whole number int
On / off bool
Colour vec3
Point vec2
Image or video sampler2D, plus a vec2 of its size named after it with Size on the end
3D model sampler2D, plus the same size vec2
Text sampler2D, plus Size, Box, Count and Glyphs named after it (see below)

Pictures are the right way up when you sample them at fragCoord / uResolution.

A Point also brings Velocity on the end of its name: how fast it's moving, in fractions of the frame a second. That's what lets a shader drag behind its own keys.

A text input called title gives you textFill(title, uv) for the letters, textDistance(title, uv) for the distance to their edge (positive inside, in frame heights, reaching 0.06) and textHalo(title, uv) for a long falloff outside them. titleBox is the word's box, and titleCount and titleGlyphs[i] give each letter's box as x0, y0, x1, y1, for moving letters one at a time.

Exporting

Export draws each frame of a shader clip as the render reaches it, at the export's size and frame rate, and passes it straight on to the rest of the render. Nothing is written to the project: a long timeline full of shaders takes no more disk than one without. Video textures are put on the exact frame for each one, so the export doesn't depend on how your machine was keeping up during playback.

The lanes under a shader clip are rendered first and handed to it, so a look that reads Lanes below sees the same composite in the export as in the player. Shader clips on several lanes are rendered lane by lane, each over everything beneath it.

An export stops with a message rather than leaving a shader out. That happens when the code doesn't compile, a texture or model input has nothing chosen, its asset has gone, or a text input's font can't be found. A very heavy shader can also make the graphics card give up, and that stops the export too.

10-bit: with Bit depth set to 10-bit in the Export dialog's Advanced controls, the shaders are drawn in 16-bit and the file is encoded in 10-bit, so gradients, glows and slow fades keep their smoothness. Where the shader is the top lane and sits plain on the frame (no move, scale, fade, keyframes or blend mode), the full 16-bit picture reaches the encoder; a shader that is placed, faded or blended is mixed with the other lanes in 8-bit first, like every other clip.

Note

The player shows a video texture close to the clock while it plays and exactly on the frame when you stop. During playback it can run slightly behind the export. Shaders need WebGL2, so an export on a machine without it stops rather than drawing nothing. HDR video reads as plain picture values with no conversion. An FCP XML export leaves shader clips out and counts them with the timecode and Lottie clips it skipped.

Sound

A shader can react to sound: a Sound input listens to the master mix, one track's mix (its gain, pan and effects included) or an audio file, and the shader gets the loudness, a beat pulse, the spectrum and the waveform for the frame it is drawing. The audio presets all have one, called Sound, set to the master mix: drop Spectrum bars or Circle visualizer on a lane and they draw from nothing; Beat pulse, Beat glitch and Bass bloom work on the lanes below, like the looks.

Nothing is measured while the clip plays. Press Bake in the Clip panel: Kitlig renders the sound once (the mix exactly as the export would hear it) and keeps a table of numbers for every frame of the clip. The player and the export both read that table, so a beat lands on the same frame in both, and a parked frame always looks the same. Until a sound input is baked the shader hears silence. Change the mix, the clip's place on the timeline, or the input's settings and the button comes back; an export bakes whatever it needs by itself. A bake is kept in the project, so it's still there when you reopen it. A track's mix is heard even when that track is muted, so a guide track you don't want in the final sound can still drive the picture.

The input's settings: Bands (how many spectrum bands, low to high), Smoothing (how slowly values fall), Gain, Beat sensitivity, and for a file Start at. The spectrum and loudness are scaled to the clip's own loud moments, so a quiet track still fills the range.

For your own shaders, an input named music gives musicLevel (0 to 1), musicBeat (1 on a beat, decaying over about a quarter second), musicBands (a texture: x is the band from low to high, y is frames back in time, so texture(musicBands, vec2(x, 0.5 / musicSize.y)).r is this frame and higher y is the recent past), musicSize (bands, history rows) and musicWave (a 256 × 1 texture of the frame's waveform, 0.5 at silence). Sound meter is the smallest example to copy from.

A texture set to peaks: true also gives your shader two sets of mip levels to read with textureLod. <name>Peak keeps the brightest pixel of the level below, for when one sample stands for a wide area and must not miss a small highlight, as Bokeh: bright lights does. <name>Soft is the picture's highlights averaged, for glow and bloom; set brightFrom to the name of a number input to use it as the threshold, as Lens flare: from highlights does.

Agents

The Video Edit Assistant, and any agent connected over MCP, can work with shader clips. They can list the starters and fonts, add a clip from a starter or from their own code, put words on a text effect, read a clip back, change its code and inputs, and keyframe a number.

A shader an agent writes is compiled before it can reach a clip. If it fails, the agent gets the errors with line numbers and the clip stays as it was.

Moving between projects

Import from Project… brings the images, videos and models a shader clip reads along with it. An input whose asset can't be brought across comes in with nothing chosen, and the export tells you so until you pick one.