线性关键帧积分器
定格(Hold)关键帧
可能在某些情况下,你宁愿使用定格关键帧来控制速度控件滑块。线性关键帧积分器表达式几乎是可行的,但并不完全可行。这里有一个微小的变化,使其适用于定格关键帧:
spd = effect("Slider Control")("Slider");
n = spd.numKeys;
if (n > 0 && spd.key(1).time < time){
accum = spd.key(1).value*(spd.key(1).time - inPoint);
for (i = 2; i <= n; i++){
if (spd.key(i).time > time) break;
k1 = spd.key(i-1);
k2 = spd.key(i);
v2 = spd.valueAtTime(k2.time-.001);
accum += (k1.value + v2)*(k2.time - k1.time)/2;
}
accum += (spd.value + spd.key(i-1).value)*(time - spd.key(i-1).time)/2;
}else{
accum = spd.value*(time - inPoint);
}
value + accum
在这个版本中,对于每个关键帧段,第二个关键帧检索的值是比实际的关键帧提前 0.001 秒,以获得进入关键帧的值。
逐帧的方法
线性关键帧积分器是一个很好的工具,但你可能会遇到它不适合你的情况,你将不得不诉诸暴力 —— 逐帧进行的选项。这个表达式本身是相当直接和简单的,但它可以让你的电脑运行相当长的时间。这是代码:
spd = effect("Slider Control")("Slider");
accum = 0;
for (i = timeToFrames(inPoint); i <= timeToFrames(time); i++){
accum += spd.valueAtTime(framesToTime(i));
}
value + accum*thisComp.frameDuration
与线性关键帧积分器一样,该表达式计算速度控制波形曲线下的面积。不同之处在于,线性关键帧积分器计算的是大块(关键帧之间的整个片段)的面积,而逐帧积分器计算的是每一帧的贡献。这意味着,随着时间的推移,表达式必须在每一帧进行越来越多的计算(以计算之前所有帧的贡献)。
将 逐帧的积分器 与我们使用了相同的滑块控件的 线性关键帧积分器 上的表现进行比较是很有用的。下图显示了逐帧积分器(青色)生成的曲线叠加在线性关键帧积分器(粉色)生成的曲线上。正如你所看到的,逐帧结果只会在帧边界处发生变化,但除此之外,它们匹配得非常好。在实践中,它们应该生成相同的动画(除非出于某种原因,你需要使用子帧分辨率)。
这显示了逐帧积分器(青色)和线性关键帧积分器(粉色)的数值结果的比较