About Variables, Linking and Expressions |
You can access information in any node and use it in a different node by linking variables and parameters.
To use a parameter inside of the same node, just type the parameter
name. For example, the Move2D node links the yScale to be equal
to the xScale by default. To get the expression editor in Shake, just
enter any letter into the text field, press Enter, and a plus sign appears
next to the parameter. Expand the parameter and edit away...
To use a parameter in a different node, use the node name, followed by the parameter name, separated by a period:
node.parameter
This example links the value parameter from the node Fade1 and
multiplies it by 2.
You can declare a variable anywhere in the script. However, to make it available
in the interface, you have to prefix it with the curve declaration:
curve parameter_name = expression;
For example, to declare the my_val variable for the above example:
curve my_val = 1;
You can clone entire nodes in the GUI by copying the node and then pressing Ctrl+Shift+V. This links all parameters in the copy to the original. If you modify anything in the copy, the link on that particular parameter is gone, so be careful of onscreen controls.
To view linked nodes in the Node View, press Ctrl+E.
You can use the syntax parameterName@@time to look at a value at a different frame:
Move2D1.yPan@@(time-1)
looks at Move2D1's yPan parameter at the previous frame.
You can declare your own variables, as shown above. However, each image node also carries with it the information about that node, using the variables width, height, and bytes. When you are referring to these, they work exactly the same as above. For example, by default, the center of rotation on Move2D is set to:
width/2
This places the center at the midpoint of the current image.
When referring to these from a different node, you place the node name before the variable:
node_name.width
In some cases, problems may occur. For example, in a Resize node, if you put the Resize equal to width/2, you cause a potentially loop because it is changing width based upon a value that is looking for the width. To solve this, Shake always refers to the input width, height, and bit depth when you refer to these from inside of that node. Therefore, width/2 takes the incoming width and divides it by 2. When you refer to the width, height, and bit depth of a different node, you use that node's output values.
At any time, you can also use the variable time, which refers to the
current frame number. For example, put cos(time/5)*50 into an angle on
Rotate for a nice rocking motion.
The following examples of using expressions, which can help out the lazy compositor by doing your work for you. In any parameter, you can combine any value with a math expression, trig functions, an animated curve, a variable, or even a conditional expression. For example, as mentioned above, the center of an image can be found by using:
xCenter = width/2
yCenter = height/2
These take the per-image variables width and height and divides them by 2.
You can type an expression in any field. Some functions, like ColorX, WarpX, and TimeX, even support locally-declared variables. See ColorX for more explanation, and also a list of examples.
If you are using the command line method, you may have to enclose your expressions in quotes to avoid problems with the OS reading the command. For example, instead of:
shake my_image.iff -rot 45*6
use
shake my_image.iff -rot "45*6"
Examples | Explanation |
1/2.2 | 1 divided by 2.2. Gives you the inverse of 2.2 gamma. |
2*Linear(0,0@1,200@20) | Multiplies the value of an animated curve by 2. |
2*my_curve | Multiplies a variable by 2. |
sqrt(my_curve-my_center)/2 | Subtracts my_center from my_curve and takes the square root of that, and then divides by 2. |
time>20?1:0 | If time is greater than 20, then the parameter is 1, else it equals 0. |
cos(time/5)*50 | Gives a smooth ping-pong between -50 and 50. |
a = 1 + 2 * 4 -2
This expression does "2*4" first since the "*" has precedence over "+" and "-" which gives you "a=1+8-2". Then from left to right, Shake does "1+8", giving "a=9-2", finally resulting in "a=7". To add and subtract before multiplying, use parentheses to control the evaluation.
a = (1 + 2) * (4 - 2)
This results in "a=3*2" or "a=6". Parentheses have the highest precedence in an expression.
Functions, Variables and Expressions |
All of the math functions can be found in the include/nreal.h file. You can declare your own functions in your own .h file.
To set an expression on a string (text) parameter, you need to add a : (colon) at the start of the expression, otherwise it is treated as text rather than getting compiled and evaluated.
Arithmetic Operators | |
* | Multiply |
/ | Divide |
+ | Plus |
- | Subtract |
Relational Operators | |
< | Less than |
> | Greater than |
<= | Less than or equal to |
>= | Greater than or equal to |
== | Equal to |
!= | Not equal to |
Logical Operators | |
&& | And |
|| | Or |
! | Not |
Conditional Expression | |
expr1?expr2:expr3 | If expr1 is true (non-zero), then to expr2, else do expr3 |
Global Variables | |
time | Current frame number |
Image Variables | These are variables carried by each node. |
parameterName | Value of parameterName from inside that node. |
nodeName.parameterName | Value of parameterName in nodeName from outside of that node. |
parameterName@@time |
Allows you to access a value at a different frame. For example: Blur1.xPixel@@(time-3) looks at the value from 3 frames earlier. |
bytes | The number of bytes in that image. This takes the input bit-depth when called from inside of the node, and the output bit-depth when called from outside of the node. |
width | Width of the image. Takes the input width when called from inside of the node, and the output width when called from outside of the node. |
height | Height of the image. Takes the input height when called from inside of the node, and the output height when called from outside of the node. |
_curImageName |
Returns the name of the actual file being used for the current frame. Useful when plugged into a Text node: {FileIn1._curImageName} |
dod[0], dod[1], dod[2], dod[3] | The variable for the Domain of Definition xMin, yMin, xMax, yMax, respectively. |
In-Node Variables | These are channel variables used in nodes such as ColorX, LayerX, Reorder, etc. Check the documentation for specific support of any variable. |
nr, ng, nb, na, nz | New red, green, blue, alpha, Z channel |
r, g, b, a, z | Original red, green, blue, alpha, Z channels |
l | Luminance channel for Reorder |
n | Null channel. Strips out the alpha in Reorder when used like this: rgbn |
r2, g2, b2, a2, z2 | Second image's channel for LayerX |
Math Functions | |
abs(x) | Integer absolute value. abs(-4) = 4. Be careful, as this will return an integer, not a float. Use fabs for float. |
biasedGain(value, gain, bias) | This gives a ContrastLum-like curve that gives rolloff between two values. |
cbrt(x) | Cubic root. cbrt(8) = 2 |
ceil(x) | Truncates to next integer. ceil(5.3) = 6 |
clamp(x, lo, hi) | Clamps x to between lo and hi clamp(1.5,0,1) = 1 |
exp(x) | Natural exponent. exp(0) = 1 |
fabs(x) | Float absolute value. fabs(-4.1) = 4.1 |
floor(x) | Truncates to next lowest integer. floor(5.8) = 5 |
fmod(x,y) | Float modulus. Returns the remainder in float. fmod(11.45,3) = 2 , ie, (3x3+2.45 = 11.45) |
log(x) | Natural log. log(1) = 0 |
log10(x) | Returns base 10 log. log10(10) = 1 |
M_PI | A variable set to pi at 20 decimal places |
max(a,b) | Returns maximum between a and b max(5,10) = 10 |
max3(a,b,c) | Returns maximum between a, b, and c. max3(5,2,4) = 5 |
min(a,b) | Returns minumum between a and b. min(5,10) = 10 |
min3(a,b,c) | Returns minumum between a, b, and c. min3(5,2,4) = 2 |
a%b | Modulus. 27%20 = 7 |
pow(x,y) | Returns x to the y power. pow(2,4) = 16 |
round(x) | Rounds number off. Values below x.5 are rounded to x, values equal to or above x.5 are rounded to x+1. round(4.3) = 4 |
sqrt(x) | Square root. sqrt(9) = 3 |
Noise Functions | These are ideal for WarpX and ColorX. |
noise(seed) | 1 dimensional cubic spline interpolation of noise |
noise2d(seed,seed) | 2d noise |
noise3d(seed,seed,seed) | 3d noise |
noise4d(seed,seed,seed,seed) | 4d noise |
lnoise(seed) | 1d linear interpolation of noise |
lnoise2d(seed,seed) | 2d noise |
lnoise3d(seed,seed,seed) | 3d noise |
lnoise4d(seed,seed,seed,seed) | 4d noise |
fnoise(x,xScale) | 1d fractal noise based on noise() |
fnoise2d(x,y,xScale,yScale) | |
fnoise3d(x, y, z, xScale, yScale, zScale) | |
turbulence(x, xScale) | A cheaper, rougher version of fnoise(). |
turbulence2d(x, y, xScale, yScale ) | Continuous 2d noise |
turbulence3d(x, y, z, xScale, yScale, zScale) | Continuous 3d noise |
rnd(seed) | Hash-based pseudo-random numbers. Non-hash based RNG (like rand() or drand48()) should not be used in Shake because they can't be reproduced from one machine to another, and even on the same machine, repeated evaluations of the same node at the same time would produce different results. |
rnd1d(seed, seed) | 1d random value |
rnd2d(seed,seed,seed) | 2d random value |
rnd3d(seed,seed,seed,seed) | 3d random value |
rnd4d(seed,seed,seed,seed,seed) | 4d random value |
Trig Functions (in radians) | |
M_PI | A variable set to pi at 20 decimal places. |
acos(A) | Arc cosine in radians |
asin(A) | Arc sine |
atan(A) | Arc tangent |
atan2(y,x) | Returns the radian verifying sin(a) = y and cos(a) = x. |
cos(A) | Cosine |
sin(A) | Sin |
Trig Functions (in degrees) | |
![]() |
Hmmm, yummy trigonometry! Welcome back. For those of you who may have forgotten, here is a helpful chart for some commonly used equations. |
acosd(A) | arc cosine in degrees |
asind(A) | arc sine in degrees |
atand(A) | arc tangent in degrees |
atan2d(y,x) | returns the angle verifying sin(a) = y and cos(a) = x. |
cosd(A) | cosine in degrees |
distance(x1,y1,x2,y2) | calculates the distance between two points, (x1,y1) and (x2, y2) |
sind(A) | sin in degrees |
tand(A) | tangent in degrees |
String Functions | |
stringf( "xyz", ...) |
Since you basically can write books on this, here is an example. Otherwise, it is recommended to purchase a book on C. There are also several examples under the Scripts documentation. This example takes the scriptName parameter and uses the system function echo to print it: extern "C" int system(const char*); |
printf( "xyz", ...) | |
strlen("mystring") | Returns the length of the string |
strsub( |
Extracts a string from another string. |
Curve Functions |
The curve functions with implicit time (Linear, CSpline, etc.) all assume that time is the first argument, so the following statements are identical: LinearV(time,0,1@1,20@20) You can, however, adjust the time value explictly with the V version of each curve type. For more infomation on spline types, jump to About Splines. These are the cycle type codes: 0
= KeepValue |
biasedGain(x,gain,bias) | Gives a smoothly ramped interpolation between 0 and 1, similar to Shake's contrast curve. gain increase the contrast, and bias offsets the center. |
Linear(cycle, value@key1, value@key2, ...) |
Linear interpolation from value at key1 to value at key2, etc. |
LinearV(time_value, cycle, value@key1, value@key2, ...) |
Linear interpolation from value at key1 to value at key2, etc. |
CSpline(cycle, value@key1, value@key2, ...) |
Cardinal-spline interpolation, a.k.a. Catmull-Rom splines |
CSplineV(time_value, cycle, value@key1, value@key2, ...) |
Cardinal-spline interpolation, a.k.a. Catmull-Rom splines |
JSpline(cycle, value@key1, value@key2, ...) |
Jeffress-spline interpolation |
JSplineV(time_value, cycle, value@key1, |
Jeffress-spline interpolation |
NSpline(cycle, value@key1, value@key2, ...) |
Natural-spline interpolation |
NSplineV(time_value, cycle, value@key1, value@key2,...) | Natural-spline interpolation |
Hermite(cycle, |
Hermite-spline interpolation |
HermiteV(time_value, cycle, [value,tangent1,tangent2]@key1, [value,tangent1,tangent2]@key2, ...) |
Hermite-spline interpolation |