Expressions
Instead of typing a static value into a parameter, write a small formula. Expressions turn parameters into living values that react to the frame, the comp and other nodes — evaluated per frame, on top of your keyframes.
Adding an expression to a parameter
Any parameter that supports expressions shows an Expr checkbox and a text field in the parameter panel. Tick the box, type your formula, and press Enter or click away to apply it. A small fx badge marks every parameter currently driven by an expression. Everything is undoable — enabling an expression, editing its text, or turning it off.
You can also pick the expression language per parameter: exprtk (the default) or tcl (see Tcl expressions).
How a parameter decides its value
Every parameter can hold three things at once: a constant value, an animation track, and an expression. Comp resolves them in a strict order:
- Expression — if enabled and valid, it wins.
- Animation — if there is no active expression, keyframes drive the value.
- Constant — the plain value you typed, used when nothing else applies.
This means you can add an expression on top of existing keyframes, and remove it later to get the animation back exactly as it was. If an expression fails — a typo, a deleted node, a divide by zero — the parameter quietly falls back to its animation or constant value and shows a warning in the panel. Your render never breaks because of a bad formula.
Which parameters can have expressions
| Parameter type | Expressions | Languages |
|---|---|---|
| Numbers (integers, floats) | Yes | ExprTK (default), Tcl |
| Text and file paths | Yes | Tcl only |
| Dropdowns, checkboxes, colors, splines | No | — |
Two expression languages
ExprTK — default
The language you get by default. Familiar math syntax with operator precedence, comparisons, logic words, a ternary conditional, and a large set of built-in math functions. Best for numeric formulas.
Tcl — optional
A simple, safe Tcl-flavoured syntax, available in builds that include Tcl support. It reads parameters and comp settings and does math — no scripting, no file or system access. It is also the language for text and file-path expressions.
The language is chosen per parameter and saved with your project. An expression never silently switches languages: if the Tcl language isn't available in your build, a Tcl expression shows a warning and falls back instead of pretending to work.
Context variables
These values are available in every expression, in both languages:
| Variable | Meaning |
|---|---|
frame | Current frame number |
time | Current time in seconds |
fps | Project frame rate |
frame_start / frame_end | First / last frame of the comp |
frame_count | Total number of frames |
comp_width / comp_height | Comp resolution in pixels |
comp_aspect | Comp aspect ratio (width ÷ height) |
comp_center_x / comp_center_y | Center point of the comp |
pi / e | Mathematical constants |
References to other parameters
Read another parameter on the same node, or on any other node in the graph:
this.opacity # own parameter Exposure1.exposure # another node's parameter this.blur_size(t-2) # sampled 2 frames in the past Source1.translateX(t+1) # or 1 frame in the future
- Use
this.(lowercase) for the node's own parameters, andNodeName.for any other node. - Node names are matched exactly, including capitalization.
- Only plain names work in references — nodes or parameters whose names contain spaces or hyphens can't be referenced.
- The
(t),(t+N),(t-N)suffixes read the referenced parameter at a shifted frame — handy for lag, echo or anticipation effects. - References link to the parameter itself: rename the node and your expressions keep working, they're updated for you.
- Circular references (A reads B, B reads A) are detected and reported instead of hanging the render.
ExprTK language reference (default)
Standard math syntax with familiar precedence. Parentheses group, and you can chain as many operations as you like.
| Category | Syntax |
|---|---|
| Arithmetic | + - * / % (remainder) ^ (power) |
| Grouping | ( ) [ ] { } |
| Comparison | < <= == != >= > |
| Logic | and or not xor |
| Conditional | ternary cond ? a : b — e.g. frame < 24 ? 0 : 1 |
Built-in functions
| Group | Functions |
|---|---|
| Core math | abs avg ceil clamp floor frac max min mod pow round sgn sum trunc |
| Exponentials & roots | exp log log2 log10 sqrt hypot |
| Trigonometry | sin cos tan asin acos atan atan2 sinh cosh tanh |
| Angle conversion | deg2rad rad2deg |
Procedural & sampling helpers
Comp adds its own functions on top of the math set:
| Function | Description |
|---|---|
random()random(seed) | A random-looking value between 0 and 1. It's fully repeatable: the same frame and seed always give the same result, so renders are stable across runs and machines. |
noise(x[, y[, z]]) | Smooth value noise at the given coordinates — great for organic drift. |
fbm(x[, y[, z[, octaves]]]) | Layered noise (fractal Brownian motion) for natural-looking variation. |
turbulence(x[, y[, z[, octaves]]]) | Layered noise with an absolute-value kick — the classic turbulent look. |
value(ref[, frame]) | Read another parameter's value, optionally at a specific frame. |
curve(ref[, frame]) | Read an animated parameter's curve, optionally at a specific frame. |
For value() and curve(), the first argument must be a plain reference like this.opacity or Source1.gain.
Examples
# pulse a blur over time this.blur_size * (0.5 + 0.5 * sin(frame / 10)) # match another node's value Exposure1.exposure * 2 # scale with the comp resolution comp_width / 1920 # ramp from 0 to 1 over the first 100 frames clamp((frame - frame_start) / 100.0, 0.0, 1.0) # procedural handheld shake Transform2.translateX + 6 * (noise(frame / 8.0) - 0.5) # switch values at a certain frame frame < 24 ? this.start_value : this.end_value # sample another parameter two frames back value(Source1.translateX, frame - 2)
Tcl expressions (optional language)
If your build includes Tcl support, you can switch a parameter's expression language to tcl. It's a deliberately simple, safe subset of Tcl-style syntax: math, parameter reads and a few lookup commands — no scripting, no file or system access.
- References work the same way:
this.param,Node.param, with(t),(t+N),(t-N)offsets. - All context variables from the table above are available.
- Logic words
and,or,notare supported.
Available functions
| Group | Functions |
|---|---|
| Trigonometry | sin cos tan asin acos atan atan2 sinh cosh tanh |
| Powers & roots | pow sqrt exp log log10 |
| Rounding | ceil floor round abs |
| Misc | fmod hypot min max |
Lookup commands
Tcl expressions can use bracket commands to look things up:
| Command | Description |
|---|---|
[value <ref> [<frame>]] | Another parameter's value, optionally at a frame. |
[metadata <key> [<default>]] | Read metadata, with an optional fallback value. |
[frame] [time] [fps] [pi] … | Context values as commands. |
What Tcl expressions don't allow
- General scripting: no loops, no variables, no running commands, no file or network access.
- Characters like
$,{ }, quotes and semicolons are not part of the supported syntax. - Very long or deeply nested expressions are rejected with a warning.
Tcl examples
frame + 1 this.translateX * 0.5 max(0, min(1, this.opacity)) atan2(this.translateY, this.translateX) * 180 / pi (frame > frame_start) and (frame < frame_end) Source.translateX(t-2) + 1 [value Source.translateX(t-1)] + [frame] [metadata lens.focal 50]
When something goes wrong
Expressions can't break your project. If a formula has a problem — a typo, a deleted node, a missing parameter, a divide by zero, or a circular reference — the parameter shows a warning in the panel and falls back to its keyframes or constant value until you fix it. Everything about expressions (text edits, enabling, disabling) is undoable.
Expressions and animation together
Expressions and keyframes are complementary, not competing. A common workflow is to keyframe the broad strokes, then add an expression for fine, procedural motion — like a handheld camera shake on top of an animated position. Turning the expression off returns you to the keys.
Not (yet) supported
- Per-pixel variables (
x,y) — expressions drive whole parameters, not individual pixels. - Convenience aliases from other apps (
mix,lerp,smoothstep, …) — on the wishlist. - Expressions on colors, dropdowns and splines; references that hop through more than one node like
A.B.C.
Put expressions to work
See which nodes and parameters you can drive.
Browse nodes