First Steps
You do not need to do very much to create expressions. First, you need a parameter to be controlled by an expression. You select the desired setting from the "Node Params" window, right-click on the appropriate value, and select “Open curve”. Now you can see the node and the associated value, but currently no curve, because you do not have any keys.
Below the curve window you can see a line with a “+” button, an input field, and an “Insert” button. With “+” you can easily merge the expression with an existing curve. The input field contains the expression you have to enter and “Insert” provides the lists with all available functions and variables. A very important issue concerning expressions is time. In RealFlow, time is either measured in frames or in the standard time code format
hh : mm : ss (hours : minutes : seconds)
By default the time line in the GUI and the curve editor use frames. If you want to use time with expressions then you have to use them in the form of variables. A variable is a placeholder that will be “filled” with values. For frames you have to use the variable “f” and for time code it is “t”. With expressions, “f” or “t” are replaced with the current frame/time from the timeline. This happens automatically so you do not have to think about it. You can also create expressions with both frame and time dependency:
sin(t * 10) * f / 20
The result of the given expression sin(t*10)*f/20.
With frames the curves show a very important difference: they look jagged and aliased, because frames only recognise integer values and the space between is interpolated by RealFlow. With time dependency, the curves are drawn smoothly. Fortunately it is not difficult to get rid of these jagged curves. Simply multiply frames by time:
(t * fps)
Frame dependencies create stepped curves and time dependencies are used to smooth them.
Expressions are not limited to frames or the time code. You can also use numbers, or even animated attributes from other nodes or properties, for example:
sin(5)
cos(Cube01.rotation_X)
Another example:
You want to create a regular up-and-down movement of an object, lets say an emitter. The first thing you have to consider is the appropriate function for this task. By looking at various mathematical functions you will see that either the sine or the cosine functions are optimal, because they already show this wave-like behaviour. The sine curve is even better, as it starts with 0.0. All functions like sine, hyperbolic cosine, square root etc. only need one parameter to work correctly. That is why they are called unary functions.
The next thing you need is a curve from the emitter’s vertical position. Please note that this can either be the Y or the Z axis, depending on your preferences. Here, we will assume that Z represents the vertical axis. Go to the emitter’s "Node Params":
Node Params > Node > Position > Z
Right-click on the value and choose “Open curve”. Now the "Curve Editor" is visible, but there is no curve or graph right now, because you have only prepared the emitter’s position attribute so far. Place the cursor into the expression field and enter
sin(t)
Confirm your entry with the Return key and have a look at the "Graph" window. The expression sin(t
)
works this way: for each frame, RealFlow calculates the appropriate sine value and applies it automatically to the Z position of the emitter. Nevertheless, the result is perhaps not what you might have expected and maybe you awaited more “hills and valleys”? What you can see is just the basic sine function in dependency on the current time. With simple operations you are able to create a denser or wider curve, higher peaks, and a positive or negative offset.
Here are a few example operations to modify the sine curve and the results:
Function | Result |
---|---|
sin(t * 5) | Sine curve compressed along the X axis |
sin(t / 5) | Sine curve stretched along the X axis |
sin(t + 5) | Shift the curve 5 units to the right along the X axis (horizontally) |
sin(t - 5) | Shift the curve 5 units to the left along the X axis (horizontally) |
sin(t) + 5 | Shift the curve 5 units up along the Y axis (vertically) |
sin(t) - 5 | Shift the curve 5 units down along the Y axis (vertically) |
sin(t) * 5 | Stretch the curve 5 times along the Y axis (“higher“ curve) |
sin(t) / 5 | Flatten the curve to one fifth in Y direction (“flat“ curve) |
It is also possible to combine functions with each other. There is no rule that expressions must consist of just a single function – in fact anything goes as long as it follows the fundamental mathematical rules:
(sin(t) + cos(t)) / (cos(t) – sin(t))
This means that it is not possible to perform division by 0 or extract roots from negative numbers, for example. Division and multiplication have a higher priority than addition and subtraction. If you want to reverse this rule, brackets are needed, as you can see from the term above. When you are working with operations like addition or multiplication, you always need two arguments. These functions are hence called binary functions, as seen here: value1 + value2 or value1 < value2
Now that you have entered the expression you are already done. Close or collapse the curve editor, press the playback button from "Timeline Control", and watch the emitter’s perfectly regular motion. Of course it is possible to create this kind of motion curve by traditional means, but it would be disproportionately difficult. So please do not be afraid of expressions: just experiment a little and you will soon find out that they are flexible, versatile and easy to use.