Function Nodes
A function node does a calculation that you write as one line, instead of wiring several math nodes together. It is the most practical way to do math in both a visual graph and an instrument: a remap, a curve, a wobble or a switch is one node instead of five.
Learn it by doing. These lessons walk you through it, step by step, in the editor:
Start lesson · Follow the coach
Where They Are
Open the Math group in the Add Node menu. The function nodes are the Float Expressions and Int Expressions, named f(x), f(x,y), f(x,y,z) and so on, up to five inputs. Visual graphs also have Vec2 Expressions and Vec3 Expressions for calculations on two- and three-dimensional values. Instruments have the float and int ones.
The number of inputs is in the name, and the inputs are called:
| Node | Inputs |
|---|---|
| f(x) | x |
| f(x,y) | x, y |
| f(x,y,z) | x, y, z |
| f(w,x,y,z) | w, x, y, z |
| f(v,w,x,y,z) | v, w, x, y, z |
Writing an Expression
Double-click the node to open its form and type the calculation in the Expression field. Press Enter to apply it. The expression is only the calculation, with no semicolon and no equals sign: x*2+1.
You can use:
- Operators:
+,-,*,/and parentheses. In Int Expressions also%(the remainder). - The inputs, by name. An input you have not wired takes the value typed on the node, and a wired input takes the value of the node it comes from.
- Functions, such as
sin(x)ormix(a, b, t)(the list is below). - Comparisons and a choice in an instrument:
x > 0.5 ? 1.0 : 0.0gives 1 when x is above one half and 0 otherwise. Comparisons are<,<=,>,>=,==and!=, and&&,||and!combine them.
Whole Numbers Are Floats
In a Float Expression, a whole number such as 2 counts as 2.0, so 1/2 is 0.5 and not 0. In an Int Expression the numbers stay integers and division drops the remainder: 7/2 is 3. Choose the node type that matches the answer you want.
Functions
These work in both visuals and instruments.
| Function | What it gives |
|---|---|
sin(x) cos(x) tan(x) |
the sine, cosine and tangent, with the angle in radians |
asin(x) acos(x) atan(x) |
the inverse functions; atan(y, x) takes two values and gives the angle of a point |
radians(d) degrees(r) |
converts between degrees and radians |
pow(x, p) |
x raised to the power p |
exp(x) exp2(x) log(x) log2(x) sqrt(x) inversesqrt(x) |
exponentials, logarithms and roots |
abs(x) sign(x) |
the size of x without its sign, and its sign (-1, 0 or 1) |
floor(x) ceil(x) round(x) trunc(x) fract(x) |
rounding down, up and to the nearest, dropping the fraction, and keeping only the fraction |
mod(x, y) |
the remainder of x divided by y, always 0 or above for a positive y |
min(x, y) max(x, y) clamp(x, lo, hi) |
the smaller, the larger, and x held between two limits |
mix(a, b, t) |
a blend from a (t = 0) to b (t = 1) |
step(edge, x) |
0 below the edge and 1 at or above it |
smoothstep(e0, e1, x) |
a smooth rise from 0 at e0 to 1 at e1 |
In a visual graph an expression runs on the GPU, so everything in the OpenGL Shading Language works too, including the functions for vectors: length, distance, dot, cross, normalize and reflect. A Vec2 Expression such as length(x - vec2(0.5)) gives the distance of a point from the middle of the visual.
An instrument only works on single numbers (floats and ints), so it has no vectors.
Naming the Inputs
x and y do not say much. Open the node’s form, click an input’s name and type a better one, such as speed or depth. The expression follows: if it said x*2, it now says speed*2, and the node on the canvas shows speed: 0.5.
A name must start with a letter or an underscore and may use letters, digits and underscores, with no spaces, dashes or dots. It also cannot be:
- the name of another input of the node,
- a word of the expression language, such as
sin,floatormix, - a value the expression can already use, such as
torframeCount, and in an instrumentnote,velocity,voiceTimeorbpm.
If a name is not allowed, a message under it says why, and the name stays as you typed it so you can fix it. Press Escape to go back to the old name.
Extra Values in an Instrument
In an instrument you can use these names in any function node, without wiring anything:
| Name | What it is |
|---|---|
t |
seconds since the Runsheet was started |
frameCount |
the number of frames since the Runsheet was started (an int) |
note |
the note the voice plays, as a MIDI number (60 is middle C) |
voiceTime |
seconds since this note started |
velocity |
how hard the note is played, from 0 to 1 |
bpm |
the project’s tempo |
So note + 12 is a note an octave up, and 0.5 + 0.5*sin(t*rate) is a value that swings between 0 and 1, with rate as an input you named.
Visuals and Instruments Are Different
- Visuals: the expression becomes part of the shader and runs for every pixel or vertex, every frame. It has to be valid GLSL, and a mistake shows when the shader is compiled.
- Instruments: the expression is worked out once per animation frame, not once per audio sample. That is right for values that control a sound: a filter’s frequency, a pitch offset, a volume that follows a curve. It is not the way to make a sound itself. For that, use an Oscillator, and use the expression to shape what it does.
Examples
| Expression | Use |
|---|---|
x*2+1 |
doubles x and adds 1 |
mix(200.0, 2000.0, x) |
turns a value from 0 to 1 (a knob, a mouse position) into a frequency from 200 to 2000 Hz |
clamp(x, 0.0, 1.0) |
holds a value between 0 and 1 |
pow(x, 2.2) |
a curve: a slow start and a fast finish, as for brightness |
step(0.5, x) |
a switch: 0 below one half, 1 above |
smoothstep(0.0, 1.0, x) |
an eased rise instead of a straight line |
abs(x - y) |
the distance between two numbers |
mod(x, 1.0) |
repeats a value from 0 to 1 over and over |
x > 0.5 ? 1.0 : 0.0 |
an instrument switch, written as a choice |
0.5+0.5*sin(t*rate) |
a wobble from 0 to 1, in an instrument, with an input named rate |
note + 12 |
an octave up, in an instrument |
When to Use a Function Node and When Not To
Use one when the calculation is a few operations and you can read it in one line. Use plain math nodes when a step in the middle is worth seeing or reusing, or when you want to wire something into the middle of a calculation. If an expression grows too long to read, split it over two function nodes. Naming the inputs usually makes a long expression understandable.
For longer logic, with several steps or your own helper, see the Custom Nodes in the Node Editor chapter, where you write a whole function.