Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity Forums Adobe After Effects Depict “slow-mo” using expressions

  • Depict “slow-mo” using expressions

    Posted by Ryan Hannebaum on January 29, 2014 at 4:30 pm

    I have a spinning cog that I would like to give off the effect of slow-motion by spinning fast at first, then slowing down gradually to a constant rate slower than the original.

    In other words, let’s say the cog is spinning (continuously) at 5 revolutions per second at first. I want to gradually slow that rate down (eased path) to 1 revolution per second, and then keep spinning at 1 rev per second continuously until a point where I speed it back up again (and it spins at 5 rev/sec continuously until I choose to slow it back down).

    I figure there is a way to achieve this simply using loopOut(“continuous”), but I’m just not quite sure of the most elegant approach, so I figured I would pick your brains.

    Thanks, and I’m happy to go into further detail if need be!

    Ryan Hannebaum replied 12 years, 3 months ago 4 Members · 12 Replies
  • 12 Replies
  • Doyle Lewis

    January 29, 2014 at 5:04 pm

    This is how I would do it.

    Create a null. Attach a slider control effect to that null then use the expression below.

    time*(360*effect(“Slider Control”)(“Slider”))

    The slider will now control the number of rotations per second. Now all you have to do is parent all the animated parts of your cog to the null (if the cog is only one part then you can forego a null if you like, I just like to use nulls for my workflow) and then keyframe your slider to change the rate of rotation.

    Doyle Lewis, Assistant Videographer

    thinkck.com

  • Ryan Hannebaum

    January 29, 2014 at 6:13 pm

    Thanks, that seems to be much much better than using loopOut()! Exactly what I was hoping.

  • Ryan Hannebaum

    January 29, 2014 at 6:27 pm

    I spoke too soon, and have one problem that should be easy to rectify.

    When I lower the value of the Slider for that expression in the Rotation attribute, the spinning actually reverses while between keyframes.

    So I have two keyframes on the Slider. The first is set to “1,” and the second is set to “0.1.”

    Before the comp gets to the first keyframe, the cog rotates 1 time per second. Perfect. After it reaches the second keyframe, it rotates 0.1 times per second. Also perfect.

    But between those two keyframes, as the value drops gradually from 1 to 0.1, the rotation actually goes backward!

    I came across this solution, but I didn’t know if maybe there was an easier way, because I don’t fully understand the solution myself…

    slider = effect("Slider Control")("Slider");
    f1 = timeToFrames(inPoint);
    f2 = timeToFrames(time);
    accum = 0;
    for (f = f1; f < f2; f++){ t = framesToTime(f); accum += slider.valueAtTime(t); } accum*thisComp.frameDuration

    Thoughts on keeping the rotation the correct direction while simply slowing down its rate?

  • Darby Edelen

    January 30, 2014 at 4:37 am

    [Ryan Hannebaum] “I came across this solution, but I didn’t know if maybe there was an easier way, because I don’t fully understand the solution myself…”

    The only other way is to manually keyframe the rotation, which is probably what I’d do.

    The expression that works in this case has a few shortcomings. It doesn’t work well with motion blur and it needs to calculate all frames prior to the current frame, so the later in the animation you go the longer it takes to calculate the value at the current frame.

    You could get around both of these problems by converting the expression to keyframes but that can become irritating if you need to change the values.

    Darby Edelen

  • Walter Soyka

    January 30, 2014 at 5:03 pm

    [Darby Edelen] “The only other way is to manually keyframe the rotation, which is probably what I’d do.”

    Or have the cog spinning at a constant rate inside a precomp, then use time-remapping to adjust its speed.

    Walter Soyka
    Principal & Designer at Keen Live
    Motion Graphics, Widescreen Events, Presentation Design, and Consulting
    RenderBreak Blog – What I’m thinking when my workstation’s thinking
    Creative Cow Forum Host: Live & Stage Events

  • Ryan Hannebaum

    January 30, 2014 at 7:00 pm

    Oh my god, why didn’t I think of that? Elegant! And that would be by far the quickest rendering option too, right? Thank you!

  • Ryan Hannebaum

    January 30, 2014 at 9:18 pm

    Hmm, I’m having a problem controlling the speed of the pre-rendered spinning cog using time-remapping. I need to be able to slow the rotation down to a new constant speed, then speed it up and have it continuously rotate at that faster speed, and so on.

    Time-remapping seems more suited for point-in-time calculations, and not continuous animation from one point on into the future. Thoughts?

  • Darby Edelen

    January 30, 2014 at 9:52 pm

    [Walter Soyka] “Or have the cog spinning at a constant rate inside a precomp, then use time-remapping to adjust its speed.”

    I suppose that is another option, but it would require the same number of keyframes as keyframing the rotation plus another step 🙂

    Unless of course you used Timewarp, Twixtor or a similar effect that actually allows you to keyframe the speed of the animation directly. These come with their own problems: poorer interpolation of the animation and increased render time.

    Darby Edelen

  • Doyle Lewis

    January 30, 2014 at 10:31 pm

    So before this i wasn’t to familiar with loops, but i think that you found the correct solution. This would probably be the simplest expression to get the result you are wanting.

    I agree with Darby that it has the downside of being a heft expression calculation wise the further you go on your timeline, and also agree with Walter that time remap would be a much easier way all the way around although If you are to do it that way i might create the animation in a higher frame rate than your final comp that way when you stretch out you time remap you have frames in between. (or use some sort of frame blending, but i don’t think that will get you the best results)

    Anyway you said that you don’t understand the expression and i thought I might lay it out for you (as best I can, I am not too familiar with this kind of expression either. If I’m wrong about anything please someone correct me.)

    the first line
    slider = effect(“Slider Control”)(“Slider”);
    is just houskeeping. It just makes the latter expression accum += slider.valueAtTime(t); easier to read instead of being accum += effect(“Slider Control”)(“Slider”).valueAtTime(t);

    the next two lines
    f1 = timeToFrames(inPoint);
    f2 = timeToFrames(time);

    Converts two time markers that will be used later in the expression into frames and defines them as variables once again just to keep the later expressions cleaner.

    The next 5 lines are a loop expression.
    accum = 0;
    for (f = f1; f < f2; f++){
    t = framesToTime(f);
    accum += slider.valueAtTime(t);
    }

    A genaric loop expression is written as such
    Variable 1 = A starting value;
    for (Variable 2 = A starting value; a statement which if ever false ends the loop; Variable 2 increment){
    a statement that will be executed every loop;
    }

    So to break down what he chose.
    accum = 0;
    His first variable he is setting to zero. This will be the value that changes in the loop dependent on the number of times the loop is run.

    for (f = f1; f < f2; f++){
    f is variable 2 and could have been named anything. There is no need to have defined f prior to this line of code. the f=f1; is saying that before any loops are ran f is equal to the number of frames it takes to get to the in point of the composition. This could just as easily be f=0 but he wrote it this way so that your animation doesn’t necessarily have to start at frame 0, it just starts at the inpoint. f < f2 is saying that the loop will continue to run until f is no longer less than the number of current frames. and finally f++ is saying to increment f by one every loop, which is why you do not need to define f before the “for” statement.

    The next line as said before is the statement.
    t = framesToTime(f);
    accum += slider.valueAtTime(t);

    There are actually 2 lines in this statement and thats because t = framesToTime(f); is just converting f back from frames into time and defining it as t. This is because the second line ( accum += slider.valueAtTime(t);) needs a value of time in the unit of time, not frames. the accum += slider.valueAtTime(t); part is saying the every loop take the value of accum from one loop ago and add the current value of the slider. the part where it is asking to add the accum from 1 loop ago isn’t naturally apparent, but exists in the operator +=. += mean take the last value and add the following. So x+=y means x= x+y it must know what the old value of x is so it can add it to y and give you the new x. What this statment is calculating is the combined value of the slider sampled at every frame. At frame 1 the slider might be 2 so accum for frame 1 is 2. at frame two the slider is still at two so the accum is 4 and so on.

    Finally the last line
    accum*thisComp.frameDuration
    This is saying that the total rotation is equal to the accum at the current frame * the number of frames there are to the current.

    Sorry for the long post, but when I was hashing out this code I wished someone had laid it out for me.

    As a side note I suggest this improvement to the expression for your specific use. Instead of the slider controlling the degrees of rotation it controls the number of rotations per second

    slider = effect(“Slider Control”)(“Slider”);
    f1 = timeToFrames(inPoint);
    f2 = timeToFrames(time);
    accum = 0;
    for (f = f1; f < f2; f++){
    t = framesToTime(f);
    accum += (slider.valueAtTime(t)*360);
    }

    accum*thisComp.frameDuration

    Doyle Lewis, Assistant Videographer

    thinkck.com

  • Ryan Hannebaum

    January 31, 2014 at 3:35 am

    Thanks for the very detailed response. Your suggestion at the end makes perfect sense too, I’ll try it out.

Page 1 of 2

We use anonymous cookies to give you the best experience we can.
Our Privacy policy | GDPR Policy