There are many ways to create interesting effects
with time remapping expressions. You’ve already seen one (the last
expression in the previous section). Here are a few more illustrative
examples.
Jittery Slow Motion
Here’s
an interesting slow-motion effect where frames 0, 1, 2, and 3 play,
followed by frames 1, 2, 3, and 4, then 2, 3, 4, and 5, and so on.
First, enable time remapping for the layer and then apply this
expression to the Time Remap property:
cycle = 4;
f = timeToFrames();
framesToTime(Math.floor(f/cycle) + f%cycle);
The first line sets the value of the variable cycle to the number of frames After Effects will display in succession (4 in this case). The second line sets variable f to the frame number corresponding to the current comp time. Next comes a tricky bit of math using JavaScript’s Math.floor() method and its % modulo operator. The result is a repeating sequence (whose length is determined by the variable cycle) where the starting frame number increases by 1 for each cycle.
Wiggle Time
This effect uses multiple copies of the same footage
to achieve a somewhat creepy echo effect. This effect actually involves
three short expressions: one for Time Remap, one for Opacity, and one
for Audio Levels. First, you enable time remapping for the layer. Then
apply the three expressions and duplicate the layer as many times as
necessary to create the look you want (Figure 1).
Note
that this time-wiggling effect is interesting, even with a single layer.
The Opacity and Audio Levels expressions are necessary only if you want
to duplicate the layer.
The expression for the Time Remap property is
wiggle() is an extremely useful tool that
can introduce a smooth or fairly frenetic randomness into any animation,
depending on your preference. wiggle() accepts five parameters, but only frequency and amplitude are required. Check the After Effects documentation for an explanation of what the remaining three optional parameters do.
The first parameter, frequency, represents the frequency of the wiggle in seconds; wiggle(1,1)
varies the playback speed at the rate of once per second. The second
parameter is the amplitude of the wiggle, given in the units of the
parameter to which wiggle() is applied, which in this case is also seconds. So, wiggle(1,1) lets the playback time deviate from the actual comp time by as much as one second in either direction.
You use Math.abs() to make sure that the wiggled time value never becomes less than 0, which would cause the layer to sit at frame 0.
The Opacity expression gives equal visibility to each layer. Here’s what it looks like:
(index/thisComp.numLayers)*100
This is simply the ratio of the layer’s index divided
by the total number of layers in the comp, times 100%. That means if
you duplicate the layer four times (for a total of five layers), the top
layer will have an Opacity of 20%, the second layer will have an
Opacity of 40%, and so on, until the bottom (fifth) layer, which will
have an Opacity of 100%. This allows each layer to contribute equally to
the final result.
If the footage has audio, you have a couple of
choices. You can turn the audio off for all but one of the layers, or
you can use an expression for Audio Levels that normalizes them
so that the combined total audio level is roughly the same as it would
be for a single layer. I think the second option enhances the creepiness
of the effect; here’s the Audio Levels expression for a stereo audio
source (for a mono source you could just leave out the second line of
the expression):
db = -10*Math.log(thisComp.numLayers)/Math.log(10);
[db,db]
This is just a little decibel math that reduces the
level of each layer based on how many total layers there are (using the
comp attribute numLayers). You’ll also notice a couple of JavaScript elements you haven’t encountered before: Math.Log()
and an array (the second line of the expression). In expressions, you
specify and reference the value of a multidimensional property, such as
both channels of the stereo audio level, using array square bracket
syntax.
Random Time
In this example, instead of having the time of each
layer wander around, the expression offsets each layer’s playback time
by a random amount. The expression you need for the Time Remap property
is
maxOffset = 0.7;
seedRandom(index, true);
time + random(maxOffset);
The first thing to notice about this expression is the use of seedRandom() and random() and the relationship between these functions. If you use random() by itself, you get a different random number at each frame, which is usually not what you want. The solution is seedRandom(), which takes two parameters. The first is the seed. It controls which random numbers get generated by random().
If you specify only this parameter, you will have different random
numbers on each frame, but they are an entirely new sequence of numbers.
It’s the second parameter of seedRandom() that enables you to slow things down. Specifying this parameter as true tells After Effects to generate the same random numbers on each frame. The default value is false, so if you don’t specify this parameter at all, you get different numbers on each frame. It’s important to note that seedRandom() doesn’t generate anything by itself. It just defines the subsequent behavior of random().
Here’s an example. This Position expression randomly moves a layer to a new location in the comp on each frame:
random([thisComp.width,thisComp.height])
Close-up: More About random()
There are several ways to use random().
If you call it with no parameters, it will generate a random number
between 0 and 1. If you provide a single parameter (as in the Random
Time example), it will generate a random number between 0 and the value
of the parameter. If you provide two parameters, separated by a comma,
it will generate a random number between those two parameters. It’s
important to note that the parameters can be arrays instead of numbers.
For example, this expression will give you a random 2D position
somewhere within the comp: random ([thisComp.width,
thisComp.height])
In addition to random(), After Effects provides gaussRandom(), which operates in much the same way as random()
except that the results have more of a Gaussian distribution to them.
That is, more values are clustered toward the center of the range, with
fewer at the extremities. Another difference is that with gaussRandom(), sometimes the values may actually be slightly outside the specified range, which never happens with random(). |
This variation causes the layer to stay in one random location:
seedRandom(1,true);
random([thisComp.width,thisComp.height])
This version is the same as the previous one, except
that it generates a different, single random location because the value
of the seed is different:
seedRandom(2,true);
random([thisComp.width,thisComp.height])
Let’s get back to the Time Remap expression. The first line creates the variable maxOffset
and sets it to the maximum value, in seconds, that each layer’s
playback time can deviate from the actual comp time. The maximum for the
example is 0.7 seconds.
The next line tells After Effects that you want the random number generator (random()) to generate the same random number on each frame.
The last line of the expression calculates the final
Time Remap value, which is just the sum of the current comp time plus a
random offset between 0 and 0.7 seconds.
Next, you would apply the Opacity and Audio Levels expressions from the wiggle()
example so that each layer’s video and audio will be weighted equally.
Duplicate the layer as many times as necessary to get the effect you
like.