Camera filters
Shader effects a camera applies to what it films, and how to add, set, animate and write them.

Camera filters are the filters in the Lens section of a camera: shader effects it applies to what it films, in the editor, the Player and exports. Stacked there, each filter works on the result of the one above it, so simple filters combine into a look of your own:
- Ready-made templates, from color adjustments and blurs to distortions, print and film looks, and generated backgrounds.
- Filters you write yourself in GLSL, or that a connected agent writes for you.
- Controls you can animate, and patterns that can stay fixed to the board while the camera moves.
A single shape has filters of its own, which work differently. See Shape filters.
An enabled filter can be hidden while you edit. Check Camera lenses in UI settings and the camera's Preview in Lens settings. These view settings leave the Player and exports unchanged.
Creating a filter

A lens filter reaches a camera in one of four ways: from a template, from a lens file, from blank code you write, or written by a connected agent.
Using a template
A ready-made filter.
- Operation: pick it in Add filter, at the top of the camera's Lens section. Type to search by name.
- Result: the filter goes to the end of the stack, or first if it is a background, with its controls at their default values. Changing its code later turns it into a Custom filter.
- Tip: Camera filter templates lists every template and describes them group by group.
Importing from a file
Filters saved from another camera.
- Operation: pick From file…, under Start in Add filter, and choose a
.lens.jsonfile. - Result: every filter in the file goes to the end of the stack, on or off as it was saved. Lens files don't hold images, so a filter with image controls asks you to choose them again. See Lens files.
Writing your own code
A filter that starts empty.
- Operation:
- Pick Blank, under Start in Add filter.
- Turn on Show code in the lens settings, and open the filter's settings.
- Write the shader code in the code pane.
- Result: Blank passes the picture through unchanged, with a comment that names everything the code can read. Once the code works, the lens draws it. See Writing lens code.
- Tip: Edit controls adds the values your code reads as sliders and fields in the filter's settings.
Asking an agent
A filter written for you.
- Operation: connect an agent, see Connect board to AI, and describe the effect you want on a camera.
- Result: the agent adds a template with the values you asked for, or writes a filter with its own code and controls, and it keeps fixing the code until it works. Later it can change the controls, reorder the filters, or rewrite the code.
- Tip: ask it to expose the values worth changing as controls.
Common settings

A filter's settings box has two groups: lens controls first, then filter controls.
Lens controls
The lens applies these settings around the filter's code, so they work the same on every filter, including a custom one, and the code in the pane never mentions them.
- Mix: every filter has it. It fades the filter from 0, where it changes nothing, to 1, its full effect.
- Edge overscan: on the filters that warp or blur. It films a band of the board around the camera, as a percentage of its shorter side, from 0 to 25, so the filter reads the shapes past the camera's edge instead of empty space. A custom filter gets it by adding a number control in Edit controls with the uniform name
uOverscan.
Filter controls
These controls belong to the filter's code: a filter has one only when its code reads it. Several templates share these:
- Anchor: on the backgrounds and on the filters that lay a pattern over the picture. Camera keeps the pattern still in the camera's view, and Board fixes it to the board, so it slides and scales as the camera pans and zooms. See Anchoring a pattern to the board.
- Picture: on the backgrounds. It sets how the generated effect combines with what the camera films. See Backgrounds.
- Speed and Time offset: on the filters that move on their own. They follow the timeline: scrubbing moves them, playback animates them, and a stopped timeline freezes them. A Speed of 0 holds the effect still at its Time offset, and on the backgrounds a negative Speed runs it backwards.
- Seed: on the filters with random detail. A different number gives a different pattern.
- Image controls: click the thumbnail to choose a file, or paste an image beside it. Once it holds an image, it can also download or remove it. An empty image control reads as black.
- Points: controls such as Center place something on the camera area, with X and Y from 0 to 1 across it, starting at the bottom left. Nine filters use them, such as Bulge / pinch, Twist and Zoom blur.
- Source: on Paper texture, Fluted glass, Water, Image dithering, Halftone dots, Halftone CMYK and Lens distortion. Camera applies the effect to what the camera films, and Image to an uploaded image. Paper texture and Water also offer None, the effect on its own. Fit, Origin X and Origin Y place the image, and show only while Source is Image.
- Colors: 14 backgrounds take a list of colors that you can add to, remove from and reorder, up to their limit of 5 to 10. With an empty list, only the background color shows, or nothing on the effects that have none.
Sizes in pixels are measured as if the camera were 720 pixels tall, so a filter looks the same in the preview and in an export of any size.
Anchoring a pattern to the board

Some filters lay a pattern over the picture: paper grain, pixel cells, halftone dots, hatching, or a background. Anchor sets how that pattern behaves when the camera pans or zooms, by hand or in an animation: on Board, the filter behaves as part of the board, so its pattern moves and scales with the shapes the camera films; on Camera, it behaves as part of the camera and stays put in the view.
-
Camera: the pattern stays put in the view, whatever the camera films. It suits effects that belong to the lens, like a halftone print look over a moving scene.
-
Board: the pattern stays with the shapes. It suits textures that belong to what is filmed, like paper under a drawing: when the camera pans, the paper slides with the drawing, and when it zooms in, the grain grows with it.
-
Operation:
- Open the filter's settings in the camera's Lens section.
- Set Anchor, the filter's last control, to Board.
- Adjust the size control, such as Scale or the cell size, if the pattern looks too large or too small.
-
Result: the pattern stays fixed to the board in the editor, the Player and exports.
-
Tip: on Board the pattern is measured in board units, so a camera that films a large area shows it smaller. A camera 720 board units tall shows it at the same size as on Camera. Scale and Rotation turn around the board's origin, and a background ignores Fit.
What the camera films
A filter works on the picture of the shapes stacked behind its camera. Where there are no shapes, that picture is transparent, and the board background shows through. This changes how some filters behave:
- Edge filters: Glow, Outline, Bevel, Drop shadow and Gooey work from the edges where the shapes meet transparency. Over a camera area filled edge to edge, such as a full image, they have no edge to work from.
- Filters that cover the whole area: Vignette, CRT scanlines and Film grain lay their color over everything, the transparent parts included, so they also darken or texture the board background.
- Backgrounds: with Picture set to Over the effect, they fill the transparent parts and leave the shapes on top.
Animating a filter

Any control of a filter can change over time, Mix included, with an Attributes Animation block on the camera.
- Operation:
- With the camera as the only selected shape, start an Attributes Animation.
- Open the filter's settings and pick the controls to animate with the pick button on each row.
- Accept, then set the start and end values in the filter's settings, with the playhead at the block's start or end.
- Result: numbers, angles, colors, points and the other values made of numbers change smoothly between the two ends. On or off controls, choices and images switch halfway. The editor, the Player and exports show the same value at the same moment.
- Tip: to fade a filter in or out, animate its Mix. To make a distortion grow, animate its own amount control, since Mix crossfades the straight and the warped picture.
Defining a filter's controls

The settings of a filter you write yourself come from its controls. Each control has a name that the code reads, and a field in the filter's settings, so its value can be changed and animated without touching the code.
- Operation:
- Open the filter's settings and click Edit controls.
- Click Add control. It arrives as a number from 0 to 1, named
uControl1,uControl2and so on. - Give it a Control label, the name shown in the settings, and a Uniform name, the name the code uses.
- Choose its Type, then set the rest: minimum, maximum and step, whether it shows a slider, or the options of a choice.
- In the code, read the value by its uniform name. The lens provides it, so the code doesn't declare it.
- Result: the control shows among the filter controls in its settings, with the field its type needs, and the code reads its current value every time the lens draws.
- Types: Number, Whole number, Angle, On or off, Choice, Range, Color, Point, Vector, Whole-number vector, Matrix, Image, List and Gradient. Writing lens code shows how the code reads each one.
- What keeps the code working:
- A uniform name must be free in the filter and usable in code; the names the lens uses itself are refused.
- Changing a control's type resets its value, and is refused when the code would stop working with it.
- A control the code uses can't be removed or have its uniform name changed. An animated control can't be removed or change type.
- Tip: Edit controls works on a template's controls too.
Writing lens code

A filter is written in GLSL, the shader language of WebGL2, in the style of Shadertoy: a mainImage function that the lens runs for every pixel of the camera area, and that returns that pixel's color. The code shows in the code pane beside the camera, and Blank gives you an empty one to start from.
What the code can read
lensPicture(uv): the picture the filter receives, which is what the camera films or the result of the filter above.uvgoes from 0 to 1 across the camera, from the bottom left. With Edge overscan on, auvbelow 0 or above 1 reads the band around the camera.fragCoordandiResolution.xy: the pixel being drawn and the size of the camera, both in pixels.iTimeandiFrame: the timeline time in seconds and the frame number. A filter that reads them moves as the timeline plays.uLensView: the camera's rectangle on the board, as x, y, width and height in board units, for patterns fixed to the board.- Each control, by its uniform name. See How controls read in code.
An example
A filter that turns the picture grey, with a Number control from 0 to 1 whose uniform name is uAmount:
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
vec4 picture = lensPicture(fragCoord / iResolution.xy);
float grey = dot(picture.rgb, vec3(0.299, 0.587, 0.114));
fragColor = vec4(mix(picture.rgb, vec3(grey), uAmount), picture.a);
}
How controls read in code
| Type | In the code |
|---|---|
| Number | float |
| Whole number | int |
| Angle | float, in radians, while the field shows degrees |
| On or off | bool |
| Choice | int, the position of the chosen option, from 0 |
| Range | vec2, its two ends |
| Color | vec4, red, green, blue and opacity, from 0 to 1 |
| Point | vec2, from 0 to 1 across the camera, from the bottom left |
| Vector | vec2, vec3 or vec4, by its size |
| Whole-number vector | ivec2, ivec3 or ivec4, by its size |
| Matrix | mat3 or mat4 |
| Image | sampler2D. An empty image reads as black. |
| List | An array as long as its capacity, plus an int named after it with Count added. A list uColors reads as uColors[i] and uColorsCount. Its items are float, int, vec2 for points, vec3 for vectors or vec4 for colors. |
| Gradient | Three values named after it: Colors, an array of vec4, Positions, an array of float, and Count. |
Two passes
Some effects, such as a blur, work better in two steps. A filter whose code has the line #define IR_LENS_TWO_PASS runs twice, with IR_LENS_PASS set to 1 and then to 2. In the second pass, lensPicture(uv) reads the result of the first, and lensInput(uv) reads the picture the filter received. Blur, Tilt-shift, Gooey, Sharpen and Drop shadow work this way.
When the code fails
Shortly after you stop typing, the lens checks the code. Code that works becomes what the lens draws. Code that fails is kept as a draft while the lens keeps drawing the last version that worked, and the error shows next to the failing line, on the filter's row, and as Lens code has errors on the camera.
Rules
- Read the picture through
lensPicture.iChannel0also holds it, but in another form and with the band included, so it draws in the wrong place once Edge overscan is on. - Leave the controls undeclared. The lens declares them, and code that declares one with another type doesn't compile.
- Measure sizes against
iResolution. Exports draw the camera at its export size, which is larger than the preview, so a size counted in fixed pixels looks different there. The templates measure as if the camera were 720 pixels tall. - Control names can't start with
gl_,ir_,webgl_, orifollowed by a capital letter, and can't be a GLSL word or a name the lens already uses. - The code can be up to 32,000 characters long.