视觉残留原理:图像在人眼当中会残留1/24秒

当前动画的三大挑战:

  1. 需要与很多gameplay互动

  2. 动画是实时的,但是动画需要存储的数据量巨大

  3. 用户对真实度、流畅度的要求高

基础动画管线

创建动画,目前主要是手K和动捕

基本动画管线:

这个是比较经典的管线,现在很多图中CPU里面的计算也放在GPU里面了

2D动画技术

精灵图序列帧

Live2D(控制网格)

3D动画技术

  • RigidHierarchyAnimation:早期的分层级的刚体骨骼

  • Per-vertex Animation:顶点动画,先离线的模拟物体每一帧的顶点和法线,再每一帧实时渲染(eg.旗帜、水流)

  • MorphTarget:其实也是顶点动画,但是每个顶点带权重,每一帧会进行插值(eg.捏脸系统)

  • 3D Skinned Animation(主流):蒙皮动画,其实2D骨骼也是这个技术

3D Skinned Animation

如图,蒙皮动画的原理,刷权重

不同参考系的空间

  • 世界坐标系

  • 模型坐标系(不是localSpace而是modelSpace)

  • 局部坐标系(Local):每一根骨骼的坐标系

实际上的动画是在LocalSpace发生的,因为骨骼的层级关系,每一个末端骨骼的坐标都系要由上一级的骨骼累加而来,所以使用局部坐标系更方便

而局部的累计算才能得出模型坐标系,从而得出世界坐标

骨骼

Skeleton For Creature:有一般骨骼基础结构

Joint or Bone:游戏记录的树状结构是Joint,Bone是刚体,没有自由度

BindAnimation:将不同的骨骼通过Joint连接到一起,如下图,人和马共同连接了一个Joint

T-pos、A-Pos:如图,T-pos是游戏引擎表示人形骨骼的标准pos,但是由于肩颈部有挤压精度不够,渐渐被A-pos取代

3D旋转数学

欧拉角

二维:如图很好推理

三维:难点是可以绕任何轴旋转,但是数学家证明:3维空间的任何旋转都可以由三个轴的旋转叠加

即欧拉角,可以自己证明

但是欧拉角有缺点,不仅仅有顺序依赖、难以插值的问题,也有万向锁的问题

四元数

对于3维空间。

实际上分别定义了i、j、k三个虚数,即三个虚轴,

且 i*j*k = -1

具体推导不深入,最终公式

最终可以表示绕任意轴旋转

四元数的优点是易于计算,可插值、可逆计算,存储空间小,一般用于引擎内部的旋转计算

JointPose 运动数据如何记录

  1. Orientation:关节旋转、四元数表达,使用一个3*4的矩阵,最后一列表示平移

  2. position:位置,齐次化为3 * 4矩阵

  3. Scale:缩放

如图:最终是一个SR的3 3矩阵表示旋转和放缩,T是一个1 3矩阵表示位移

动画一般存储在LocalSpace里面,即只存储相对于父节点的变化

为什么要存在局部坐标

如图,在模型坐标系下,插值出来的值为直线

关节与骨骼的映射关系

在关节移动时,骨骼上的Skin也需要做相应的仿射变换

上图为:每一个关节的模型坐标是由父节点的模型坐标相加而来

顶点的模型空间位置 = 关节的模型坐标 顶点相对关节的位置 = 关节的模型坐标 关节绑定模型坐标的逆 * 顶点绑定模型坐标

即:顶点绑定模型坐标 = 关节绑定模型坐标 * 顶点相对关节的位置

所以有:

即:顶点相对关节的位置(局部坐标) = 关节绑定模型坐标的逆 * 顶点绑定模型坐标,称为SkinningMatrix

所以在计算机中,关节处存储的都是绑定模型坐标的逆,如图

如何通过蒙皮权重计算蒙皮位置

其实就是一个加权平均,这个插值必须是在模型空间发生的

动画切片Clips

即在动画切片里面插值

位移和Scale是直接使用线性插值,但是旋转的插值会更加复杂

NLERP

如图,旋转的插值是使用四元数进行线性插值之后,在进行一个归一化,这就是四元数表示旋转的方便之处

注意点是,如果是大于180度的角度插值,需要进行反向插值,即最短路径的插值

以上方法称为NLERP,但是这个方式有一个缺点是,插值出来每一个角度分配的时间是不均匀的,如图,中间部分更慢,越接近起始点和终点越快,动画会不自然

SLERP

针对NLERP的问题,许多3A游戏有另一套插值方法,SLERP

即不使用矩阵插值,而是使用角度插值,但问题是运算量大,且当角度很小的时候插值不稳定

实践中的方法

一般会给定一个magicNumber,小于该角度使用NLERP,大于该角度使用SLERP

动画RunTime优化

动画压缩

动画的数据量其实是很庞大的,每一个Pose的关节坐标和clip里面的坐标变换

对大部分骨骼动画,数据大多是Rotation,而且许多关节是自身不移动的,所以动画首先是除开一些没有位移的放缩的数据

关键帧插值:

Catmull-Rom Spline:如图,是一种插值计算的数学方法,推导不重要

即将每一帧进行Catmull-Rom插值的结果计算出来,与正确结果作为比较,超过误差阈值就舍弃,并将下一帧作为关键帧,这样就能把原本的帧数压缩为少数关键帧

四元数中的浮点数压缩

可以使用定点数模拟,即使用区间映射将浮点数转化为定点数

而且可以根据四元数的特性,只存一个最大数,剩下的三个数可以通过计算还原

所以如图,原本四个浮点数可以只用6byte存储

压缩的问题

因为使用了许多压缩,会使动画有一些误差,但是由于骨骼坐标会向下累加,这些误差会放大传递到关节末端,称为Error Propagation

所以需要使用一些方法定量估计压缩前和压缩后的误差

可以通过调整末端骨骼进行误差补偿

高级动画技术

动画Blending

即从一个动画到另一个动画的过渡——线性插值(NLERP、SLERP)

但是为了避免两个动画的相差过大,一般要求两个动画进行Timeline Align

这里的blending例子权重是由一维变量决定的

Blend Space

当动画Blending需要多个变量控制时,即需要多维变量的混合动画

混合动画的算法:如图,根据二维上的点坐标找到临近的三个动画组成的三角形,再通过中心坐标进行插值

动画Mask

通过遮罩使不同的骨骼部位应用不同的动画

Additive Blending

即在原本的动画上再加一层相对量的数据,达到再加一层动画的效果

比如,在原本的动画上再加一层点头的效果,只增加相对量,而不是绝对量

Animation State Machine(ASM)

动画状态机:由节点和变换条件组成,节点包括动画切片和混合动画

Fade

  • Smooth Transition:动画1权重减少,动画2权重增加

  • Frozen Transition:动画1停止,动画2逐渐增加权重

Fade曲线:

分层状态机 LayerASM:使用LayerMask实现角色不同骨骼位置拥有单个动画状态机,现代多使用BlendTree

BlendTree

动画树的核心是定义控制变量,通过变量控制混合权重(比如在UE动画蓝图中获取pawn参数保存本地)

IK (Inverse Kinetics)

基础概念

反向动力学:以骨骼末端影响动作,比如脚掌贴合地形,手掌持枪

以Two Bone IK为例,只影响两根骨骼,如图:

已知两根骨骼边长和大腿骨骼根部到目的点的距离,使用勾股定理和三角函数可以计算出两根骨骼的偏移角度

并且需要规定这个三角形的朝向,因为上述解法的解空间在三维世界中是一个圆,无法确定一个唯一解

不然的话,例子中的关节可能会呈现不符合人体的形变

如何判断IK中的关节走向

连接多个关节时,每个关节都会有无数种偏移量符合解,需要找到一个符合人体的唯一解,如上述的TwoBonesIK,需要确定唯一解

首先判断是否能够到达目标点,计算骨骼最大距离和盲区

其次需要确定人体关节的活动范围限制

CCD算法(cyclicCoordinateDecent)

目标点依次连接每个关节,循环翻转

CCD也有非常多的优化方式,比如规定翻转最大角度,越到根节点角度越小,使翻转的角度尽可能的均摊到每一个骨骼

FABRIK (Forward And Backward Reaching IK)

首先连接末端骨骼与目标点,直接改变骨骼位移,然后连接下一个骨骼与末端骨骼位置做位移,递归到根骨骼,然后根骨骼又连接根位置,来回递归

如何处理多个IK

比如角色攀岩时,需要同时计算双手双脚四处IK,而这四处IK的根骨骼可能是同一个,每一个IK的计算都会对根骨骼有影响

解决方法:Jacobian Matrix(雅可比矩阵),在物理系统中会详讲

IK如何影响动画管线

如图,在一个动画管线当中加入IK之后,图中标黄的部分,先是使用混合树计算模型坐标系和世界坐标系,然后计算IK,得出新的世界坐标

表情动画

使用顶点动画MorphTarget,通过存储顶点相对于neutral表情的偏移量进行插值计算

如图:

其实除了顶点动画,也有少量的骨骼动画控制,比如眼球移动

动画重定向

动画本身记录每根骨骼相对于原始Pose的位移,所以重定向之后依旧只会根据动画的相对位移计算新的动画

不同角色骨骼的比例不同,解决位移动画问题:计算等比例位移,并且需要做一些IK

解决骨骼映射问题,会根据同名骨骼进行映射,针对同名骨骼之间多出来的骨骼会进行0-1的映射

Morph Animation重定向

对于顶点动画也是可以重定向的,因为这类动画(人物表情)也是只计算了对于neutral状态的相对偏移量。

不过依旧有一些偏差,比如眨眼动画的重定向,有些角色可能出现闭不上眼的问题,所以也有一些约束点来使动画更自然

总结

Blending系统(ASM、BlendingTree)是核心,连接gameplay系统,通过参数调整角色动画

其次使用顶点动画做人物表情,重定向技术适配不同角色骨骼