(Page 3 of 3 pages for this article < 1 2 3)
Sunday, July 04, 2010
Deeper Modes of Expression, Part 7: Making Decisions
Chris Meyer | 07/04
Learning how to craft if/then/else statements plus do/while loops will open the door to a wide range of advanced techniques.
While You Wait
This is the most advanced topic we’re going to discuss in this series. If you are still new to expressions, feel free to skip this section for now.
Perhaps the greatest weakness of expressions is that they have no memory. They execute fresh each time the time indicator moves to a new frame, with no recall of what they did the frame before. Yes, you can use the valueAtTime method demonstrated in the previous installment to see what a property’s pre-expression value was at an earlier point in time, but you still don’t know how you got there.
This becomes a big issue if you are trying to create “simulation” types of expressions. For example, say you wanted to keyframe the amount of throttle being applied to a motorcycle – and you wanted to write an expression that automatically rotates the motorcycle’s wheels in response. To know how much the wheel should be rotated by the time you reach a certain frame, you need to know how much it had been rotated by the frame before…which needs to know how much it had been rotated by the frame before that…which needs to know…you get the idea. As a result, an expression needs to walk frame by frame through a comp from the beginning until the current time, accumulating results as it goes.
To create these types of simulations, you need to create what is known as a while/do loop. An if/then statement executes only once and then is finished, regardless of whether the answer to the “if” question is true or false. By contrast, a while loop executes the “do” statement (equivalent to an if/then’s “then” statement) and then returns back to the top until the answer to the “while” question is finally false.
Typically, a while loop will use a variable to count how many times the loop is executed, and exit the loop only when this counter reaches a certain value. In our example of walking through a comp’s timeline, a while loop would start at frame=0, see if that time equaled our current frame, and if not, our expression would keep adding a frame at a time to our counting variable until it finally reached the current frame number. Inside this loop, you can then add code that accumulates the data you need. This is what the basic format of this loop would look like (using a nifty method discussed in an earlier installment that converts time in seconds to much easier-to-handle time in frames, at the current frame rate):

The figures below shows the expression and resulting Graph Editor display for our aforementioned motorcycle throttle example. The pink line is the throttle amount that uses an Expression Controller > Slider Control to represent the throttle setting from 0 to 100%. We’ve keyframed it to represent the throttle being varied over time, including stopping. For the sake of this simulation, we’ve decided that at full throttle, the wheel should rotate 20 degrees per frame (which translates to the throttle setting of 100% divided by 5). The turquoise line shows the resulting total rotation; note how it increases while the pink throttle line is above zero, and is flat and horizontal when the pink throttle line is at zero:

(Notice the stairstepping in the turquoise graph? That is the result of the expression calculating a discrete value per frame, in contrast to normal keyframe interpolation which is smooth. More in that in a sec…)
Using techniques we discussed near the start of this series, we also decided to add a bargraph display and numeric readout to the left side of the comp that represents the amount of throttle being applied.
What if we planned on field rendering this composition, which means we would be rendering two images per frame? Then we would need to calculate a new result twice per frame. To do this, we would need to increment frame by a half-frame (frame + 0.5) each pass of the loop, and increment total_rot by only half as many degrees each pass (as we would be adding degrees twice as often).
While loops can take awhile to execute - especially in long compositions where they have to walk through a large number of frames. Remember that you can “bake” the result of any expression into keyframes, which execute much faster. To convert the results of an expression into keyframes, select the property with the expression, and use Animation > Keyframe Assistant > Convert Expression to Keyframes. The expression will not be deleted; it will just be disabled.
By the way, motion blur does not work well with animations driven by while loops that count time by frames – there are no intermediate values between frames to create the multiframe blur effect. If you need motion blur for an expressed animation, fake it with a blur plug-in, count time by much smaller increments, or convert your expressions to keyframes before you render.
“While” loops are pretty cool, and they open the door to a whole new family of complex animations, but again you should ask yourself if this is the easiest way to solve a particular problem. For example, this comp would have been much easier to set up if we had keyframed the rotation of the wheel, and then used a velocity expression (discussed in a previous installment) to derive the throttle amount.
Accumulating Numbers
Loops often use numbers that you have to increment – for example, a count of which frame number you are calculating. JavaScript (and by extension, expressions in After Effects) has some special math operators that make it easier to accumulate values.
For example, in our examples for “while” loops, we use the statement step_time += thisComp.frame_duration. The += symbol is called an “add-and-assign” operator. What it means is, take the number on the left, add the number on the right, and store the result back into the number on the left. It means the same thing as saying “the new value for step_time equals the old value for step_time, plus the length of a frame.”
Other similar operators include:
–= subtract-and-assign
*= multiply-and-assign
/= divide-and-assign
Next Installment: Going for a Loop
Is your head spinning after all this? Don’t worry; in our next installment, we’ll discuss the much simpler concept of looping animations - based on time or keyframes. Until then…
We’re in the process of serializing the Deeper Modes of Expression bonus chapter from our book Creating Motion Graphics with After Effects into a set of 12 posts here on PVC.
The next edition of Creating Motion Graphics - for After Effects CS5 - is out now.
The content contained in Creating Motion Graphics with After Effects - as well as the CMG Blogs and CMG Keyframes posts on ProVideoCoalition - are copyright Crish Design, except where otherwise attributed.
(Page 3 of 3 pages for this article < 1 2 3)
You must be registered to comment. This is an effort to reduce spam. Please REGISTER HERE.
|