如何为离线渲染创建 bezier/cubic 简化动画?

How to create a bezier/cubic simplified animation for offline render?

我必须为正在离线计算的元素设置 alpha 动画。让我们谈谈简单的 alpha 动画。 Alpha 为零,alpha 增长到 1,停留一段时间然后回到零。

类似于下图:

动画会有不同的时间。我需要一些我可以给时间 (t) 并获得价值 (v) 的东西。

此动画将放在基于 CIFilter 的 class 中并用于为该过滤器设置动画,并且由于此过滤器的结果将离线计算,因此没有 CALayer添加它,所以使用 CAKeyframeAnimationCABasicAnimation 是不可能的。

如果我可以使用 CALayer,我会这样做:

CABasicAnimation* fadeInOut = [CABasicAnimation animation];
fadeInOut.keyPath = @"filters.myFilter.inputRadius";
fadeInOut.fromValue = @(0);
fadeInOut.toValue = @(10);
fadeInOut.duration = 0.2f;
fadeInOut.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseInEaseOut];
fadeInOut.autoreverses = YES;

但问题是这一行...没有添加动画的层。就像我说的,我在 CIFilter class!

里面
[self.layer addAnimation:fadeInOut forKey:nil]; // NO WAY!

所以,我的问题是:对于我为动画定义的时间间隔,有什么东西可以给我这种曲线的时间值吗?

您正在 class 制作 CIFilter 和动画...我想这意味着您的过滤器 class 需要一个时间参数,并根据该参数改变其结果?

如果是这样,您可以考虑两种选择。两者都依赖于这样一个事实,即您想要的时序曲线看起来像 "ease-in-ease-out" S 曲线,然后是该曲线的反向。

  1. 如果您正在编写 CI 内核语言代码来实现过滤器的效果,您可以使用 the smoothstep function (that function is defined by GLSL, and CI Kernel Language is a superset of GLSL except where defined otherwise 根据您的时间参数进行插值。因为你有双 S 曲线,你需要做两次:

    // pseudo CI Kernel source:
    effect = smoothstep(0, 0.5, time) - smoothstep(0.5, 1, time)
    
  2. 如果您不是在编写内核,而是根据其他过滤器实现一个过滤器,您可以定义自己的 smoothstep 函数的等价物——该定义在 well known and fairly simple, since it's in many graphics libraries. (Or you can learn about Hermite interpolation一般并使用您自己的平滑函数。)然后使用您的函数根据您的时间参数更改内部过滤器的输入。