AE 表达式:posterizeTime 与 time 的取值陷阱
基本概念
time是时间条的值(time indicator指到哪里,它就是多少)
posterizeTime()既有表达式,也可以直接用effects。常用于抽帧,表达式的意思是设置该值每秒刷新多少次。
使用posterizeTime()的优先级问题
假设在60fps的合成中,有两个图层,他们x位移的表达式分别是:
//假设该图层名为"Shaper Layer 2"
posterizeTime(2)
time * 300//假设该图层名为"Shaper Layer 1"
time * 300 则我们能看见 Shape Layer 2 图层的位移变化呈现抽帧效果。
但是,如果 Shape Layer 2 的表达式写为:
posterizeTime(2)
thisComp.layer("Shaper Layer 1").transform.xPosition则它的刷新率会回到60fps,呈现出与 Shaper Layer 1 相同的运动状态与帧率——这是为什么?
原因在于,posterizeTime(2)影响的是本层的fps,进而可以说影响的是time值,而不是value。而底下的thisComp.layer("Shaper Layer 1").transform.xPosition是绕过time直接对value的取值。
建立一个文字图层,对source text的取值表达式写成:
posterizeTime(2)
time就可以发现这一点。也因此,解决办法也就很明显了。
解法1:valueAtTime()传入posterizeTime的取值
- valueAtTime() 括号中要求一个时间值,返回在这个时间的value。
posterizeTime(2);
thisComp.layer("Shaper Layer 1").transform.xPosition.valueAtTime(time) 将被posterizeTime()影响过的time值传入valueAtTime()中,从而实现效果。
解法2:Math.floor()与valueAtTime()
-Math.floor() 向下取整
豆包还为我们提供了稍微麻烦一点的解法。
首先,将 Shaper Layer 2 的x位移写成:
fps = 2;
t = Math.floor(time*fps)/fps;
thisComp.layer("Shaper Layer 1").transform.xPosition.valueAtTime(t)首先,我们希望的效果(抽帧)的本质是<u>让画面**每秒**刷新固定的次数</u>,那么只要能让画面每一秒刷新到我们指定的次数,就可以实现这个效果。
此时,Math.floor这个向下取整函数就至关重要了。
使用fps与t两个变量:在 fps = 2的时候,t达到0.5时刷新一次,达到1时刷新一次。同理,fps = 3时,Math.floor(time*fps)在0.333...秒时才能取到1,t才能取到1/3,才能返回到1/3秒时的Shaper Layer 1的x位移值...
总的来说,这个方法像是自己写了一个posterizeTime(),但区别在于:在这个示例中,time值本身未被影响,影响的是变量t。全程使用用户命名的变量来实现抽帧效果。