 |
Fibbonacci Spiral Lattice and Noise Based Lighting tutorials coming soon.

|
| Periodic Functions |
|
Often when you want to find a procedural solution to animation, periodic functions will be involved (functions that repeat themselves endlessly).
I'll cut to the chase and show a few and what you might use them for, we'll go in depth towards the end.
Each graph in the first section can be seen in motion by hovering over the image with your mouse.
Some browsers will play smoother than others, but the concept should come through even with a little jitter.
Sin Wave
sin(time)
Here is the simplest and most well known periodic function, seen here for a pendulum with the function on rotation.
A slightly more complicated setup for this would be a color rotation constantly cycling through colors. Here the function controls the RGB values directly.

Saw Wave
time-floor(time)
A saw wave travels linearly from one value to another and resets back to its original. This is perfect for a jacob's ladder.

Square Wave
floor(time)%2
This is a square wave, or on/off switch. This is great for blinking lights, or turning other functions on and off.
Note: Substitute n for 2 where n is the number of steps you want to repeat. in this example we have 4 steps that repeat.

Now is about time for the honorable mentions: Random and Noise. They don't technically repeat, but they do go on forever.
Random is just that, random, it's jittery, unorganized, unpredictable. But, we do need a way to break up the perfection of a sin wave. Enter: Noise.

Random rand(-1,1) |
Noise noise(time) |
Ahh noise, how awesome you are. For those unfamiliar with the noise(time) function, the short explaination is a representation of a vertical slice through a procedural noise texture. What that means is you get a variety of values that are seemingly random, yet they have an ebb and flow to them, rather than being jittery. You have control. If you happen to be in a program that does not have a native noise function, you can aprroximate it by multiplying sinwaves together: sin(time*7)*sin(time*5)*sin(time*3)*sin(time*11.5)...... the more you do, the more varied the result.
There are many others, but from these simple functions, we can get just about any shape for any purpose, combined with the power of 1.

|
Curve Manipulation and The Power of 1
|
Physics/Calculus Majors will tell you there are three numbers that matter: 0, 1, and the rest. One of the many reasons is because 0 and 1 are the only two numbers that share an interesting phenomenon - if you multiply them by themselves, you get... themselves. 0*0=0, 1*1=1. That may seem trivial, but it allows us to do a lot of manipulation.
Let's go back to the saw wave. We can start bending the curve up or down with a pow (exponent) function:
pow(time-floor(time),n)
where n is the power that is bending the curve up or down.
Use values between 0 and 1 to bend the curve up and values above 1 to bend the curve down.
 |
pow(time-floor(time), 3)
pow(time-floor(time), 1)
pow(time-floor(time), .33) |
Now with the fundamentals out of the way, it's time to start manipulating the curves to suit your needs. Every periodic function can be scaled in time or value using the following method:
sin(time*a+b)*x+y
where:
a = longer or shorter durations between cycles (frequency)
b = an offset in time of a given cycle
x = higher or lower values within the cycle (amplitude)
y = an offset of the value range
 |
sin(time*3+10)
sin(time)
sin(time)*.4-.7 |
For ease, it is best to get a functions return values into the 0-1 range because your equation becomes very easy to change intuitively. If we are dealing with a saw wave or square wave (where the values are already 0-1), using the equation above, x = the range of the value and y = the minimum value.
for example:
(time-floor(time)) * 8 + 2 would give us a range of 2-10; 2 is the minimum value, 8 is the range (8+2=10 = max value)
 |
(time-floor(time))
(time-floor(time)) * 8
(time-floor(time)) * 8 + 2 |
to get a -1 - 1 value function like sin or noise to 0-1, simply multiply by .5 and add .5.
sin(time)*.5+.5 will give you a sinwave that ranges in value from 0-1. From there manipulate as needed. It is not always neccessary to take the step to go to 0-1, but when dealing with ranges of value from 37-468, it becomes easier to start from the simpler state of 0-1.

There are many uses to combining and altering these functions to different purposes. Here are some examples of how to combine functions to get various effects.
floor(time)%2*(time-floor(time)) - pulsing light with pauses

abs(sin(time))*pow(time-floor(time),2) - steady but varied emission cycle

(sin(frame*2)*linstep(4,30,frame)*.2 + sin(frame*4)*smoothstep(30,31,frame) - sin(frame*4)*linstep(31,43,frame) - sin(frame*2)*linstep(43,90,frame)*.2) - procedural camera shake with ramp up, impact, and settle.

These can be used for emission rates, colors, transparency, really anything you can think of. This provides a nice alternative to hand creating dozens or hundreds of keyframes, and the curves can be manipulated very quickly once you get the hang of it.
Once you start using them, you'll find more and more uses.
Check out my Noise Based Lighting Tutorial (coming soon) for an advanced application of these techniques.
Happy mathing! If you have any questions, feel free to email me.

Quick cheat sheet for reference:
Normalized Sin Wave:
(sin(time*a+b)*.5+.5)*x+y
Normalized Noise:
(noise(time*a+b)*.5+.5)*x+y
'Bendable Teeth' Saw Wave
pow((time*a+b)-floor(time*a+b), n)*x+y
Square (Step) Wave
(floor(time*a+b)%n)*x+y
don't forget about pow, abs, %, ceil, and floor functions for additional manipulation.
|
|
|
|
|
|