什么是动画管线?UE虚幻引擎实现机制?
什么是动画管线
动画管线指一系列运算,把输入(动画资源、混合设置),变换成输出(局部及全局姿势、渲染用的矩阵调色板)。
定义有些抽象,简单理解,就是把生成一个动作的处理,分三个逻辑阶段,输入一些数据,得到一个姿势。
逻辑上分三部分,采样、融合、后处理。大致流程是,采样需要的多个动画,加上各种参数、条件做融合,之后后处理,输出的一个姿势。
UE实现机制
不同于渲染管线,动画管线是个抽象概念,UE里通过节点实现。对应管线的三部分逻辑,UE实现上也是分别实现这三个逻辑。
采样
分两部分,一是采样数据,由资源提供接口。二是外部驱动流程。
采样接口
- 由资源实现,UE提供了几种资源,基础的是UAnimSequence,采样接口在这实现。其他资源,是对资源的另一层封装,包括混合空间和蒙太奇,蒙太奇是个实用的扩展,后面细说。真正的采样都是GetBonePose方法。
- 核心逻辑是,外部传递一个时间(保存在FAnimExtractContext结构体中),取到邻近的两帧,结合设置的插值算法,返回数据。实现上要比描述的复杂一些,涉及到压缩相关的处理。
- 采样的结果,不只是骨骼数据,还包括曲线和属性,这些都是跟动画帧变化的数据。
- 分3个方法计算:EvaluateCurveData、DecompressPose、GetCustomAttributes。
流程
- 首先由状态机选择要播放的动画,对应FAnimNode_AssetPlayerBase节点,触发采样需求。
- 采样资源之前,先计算时间,因为要加上动画本身的播放速度。由link节点调用UpdateAssetPlayer,在资源有效的情况下,计算当前动画时间(判断有效范围,加上播放速度)。
- 然后从link节点调用Update_AnyThread,执行节点的Update逻辑,获取时间对应的数据,保存在FAnimationPoseData,包括姿势、曲线、属性。
融合
融合的效果是将多个动画,按一定算法,生成一个动画。
基础是变换运算
- 对姿势做基于权重的运算。
- 两种方式,由BlendTransform函数实现。
1. 基于权重的覆盖:目标变换=源变换*权重2. 叠加:目标变换=目标变换+(源变换*权重)
姿势混合有3种方式
1. 线性插值:两个姿势的中间姿势,各有权重,用于动画过渡。权重的算法,可以实现不同的曲线,对应不同融合效果。
2. 加法混合:用于叠加,一般是基础动画,加上一个特殊状态,比如在基础的移动上,叠加上受伤、拿武器等。优点是可以用组合的方式减少资源。
3. 骨骼分部混合:不同骨骼分别播动画,按部位分离,也是可以减少资源,有些动画控制特定骨骼就可以了,比如实现上半身攻击下半身移动的效果。
融合一个作用是动画过渡
- 标准过渡:源动画到目标动画的过渡。指定时间段,用线性插值实现。这是个基础的过渡。
- 惯性过渡:当前姿势到目标动画的过渡。有些时候,标准过渡效果不一定好,比如在跑的时候起跳,如果融合跑和跳的动作,看起来就是在空中还在跑,这时用惯性过渡可能更好。UE已经有对惯性过渡的支持,Unity好像还没有,最近没关注。
- 融合触发方式
1. 采样资源时直接做融合,由扩展的资源实现。
2. 通过指定的节点,输入多个pose做融合。
核心算法实现,在FAnimationRuntime类,节点和资源会调用这个类的方法。
后处理
作用是对动画姿势做校正,主要是各部位的IK,因为做动画的时候,生成的是和环境无关的姿势,而实际运行中,动作要和周围的环境有一定的匹配,这样才显得更真实。
具体算法由FAnimNode_SkeletalControlBase子类实现,UE实现了多种IK算法,之后在细看看每种算法的实现逻辑。Unity/UE虚幻引擎学习加betabot2