02 - 引擎中的高级动画技术

本文将对游戏引擎中的高级动画技术做一些介绍,比如动画的混合,动画状态机,IK技术,动画重定向等。

动画混合

在游戏中,一个或多个动画序列帧需要以特定的规则组合贡献给最终的角色,这种规则就是动画混合。动画混合是游戏引擎中动画模块的重要组成部分。

线性插值混合

可以用LERP在多个动画序列帧之间进行差值,以达到数学上的混合效果。需要和前面单个序列帧的不同关键帧之间插值作区分。

计算混合权重

需要按照混合权重进行插值计算。以走路动画和跑步动画的插值为例,选择当前人物速度、触发走路动画和跑步动画的速度作为计算混合权重的参考值,计算出两动画各自的混合权重,然后进行插值。

对齐混合时间线

由于两动画播放的时间还不一样,如何在播放时间不一样的动画里选关键帧插值很重要。首先要求做动画的艺术家将动画的形式尽量一致,如必须是循环的,都是左脚一步右脚一步。然后要将两个动画的时间线归一化,方便插值计算。

混合空间

以玩家的方向移动为例,来看看动画的混合空间是什么。

一维混合空间

目前只有一个自变量:玩家的移动方向。因此就是1D混合空间。其中,采样点可以有多个,例如向前移动,向左移动,向右移动等。

二维混合空间

除了移动方向外,实际上还有速度这个自变量。这样就得到了一个二维的混合空间,其中每个采样点均为一种动画素材。

此外,在艺术家的要求和真实性考虑下,动画采样点往往是不均匀的。

我们在计算动画混合时,也不需要去计算所有种类动画的混合,这太麻烦了。而是利用 Delaunay三角化,将采样点划分为一个个三角形,根据三角形重心坐标插值找到采样点所属三角形,最后只混合三角形三个顶点上的动画。

骨架遮罩混合

有时候我们需要在做一段动画的同时做另一段动画,这时候就需要用到骨架遮罩,让上半身做上半身的动画,下半身做下半身的动画,最后混合到一起。

附加混合

在动画混合全部做完后,如果还想让它做额外的动画,可以使用附加混合添加一个差分动画做修饰。例如一直在点头。

这种混合要做的很谨慎,因为它是基于其他混合的叠加,稍有不慎就会发生一些异常现象,例如一些扭曲。

动画状态机ASM

有时候也会碰到动画状态切换的问题,和上面动画灵活过渡的动画混合不同。例如简单的跳跃操作由三个小动画组成,分别对应三个状态,它们之间有序切换。

定义

状态机由各种节点和箭头组成,其中节点可以是上面提到的混合空间,也能是序列帧动画。

而箭头则是状态切换的条件(Transition),例如玩家要跳跃时,要从Idle状态切换到jump_start_from_idle状态。需要有起点和终点索引信息,以及是否要混合插值。

例如UE引擎的动画状态机,双箭头是状态切换条件,连接状态节点。

CrossFade

这是状态切换间常用到的过渡方法,分为平滑过渡和冰冻过渡两种:

此外,还有多种控制过渡程度的曲线供艺术家选择:

多层状态机

早期可以给角色设置多层状态机,每层状态机独立控制角色的一些动画。

动画混合树

现在人们开始使用动画混合树来代替多层状态机了,它的思想基于表达式树,通过对一些动画做“表达式运算”,从而得到最终的动画。

节点

动画混合树有多种节点,接下来看看有什么。

LERP混合节点

分为简单的双通道线性混合节点与多通道线性混合节点两种,区别在于混合权重的输入。

附加混合节点

UE引擎动画混合树的节点则更加泛化灵活,叶子节点除了可以是动画序列帧外,还能是混合空间、ASM等。

表达多层状态机

动画混合树也能表达多层状态机,可以说它是多层状态机的超集。

控制变量

在动画混合树中,会定义大量暴露给GamePlay系统的控制变量,以改变混合树的行为,获取实时输出。

反向动力学IK

之前说的都是前向动力学的内容,由因得果;而反向动力学IK(Inverse Kinematics)则要求你根据约束好的结果求解初始状态的关节是什么样。

两骨骼约束IK

假设要控制一个角色行走,为了能让它的脚自适应地形,需要用到IK。容易实现的IK是双骨骼(三关节)约束的IK,知道两条腿的信息便能根据三角学知识求出大腿和小腿的摆动幅度。

但实际上在3D空间,两骨骼约束IK的解是一个圆环,因此会有下图这种解不可控的情况。

为了让结果可控,可以用一个方向向量进行约束,只使用该方向上的解。

多骨骼IK

除了双骨骼(三关节)IK外,还有更复杂的IK,例如下图中的各种IK,涉及到的关节很多。

多关节IK的求解很复杂,首先计算过程是高维度的,其次求出来的解有很多、唯一解或无解。

计算可达性

在正式求解多骨骼IK时,需要计算它的可达性。一种方法是把所有骨骼拉直,看看能不能到达目标点。另一种方法是把所有骨骼往最长的骨骼那边折,看看能不能到达目标点。

解的合理性

对于骨骼IK还要注意解的合理性,例如人体关节是不能乱转的,具有约束性。

常用算法

对于多IK约束的求解,常用到启发式算法。这类算法可以较高效地应对高维求解问题,可以只求出近似解而加快计算效率。

循环坐标下降法CCD

从末端关节开始,尽量让所有关节都靠近目标点,进行多次迭代求解。

CCD算法还有一些优化:

  1. 给每个关节的目标点设置一个容忍区间,这样可以让动作看起来更加合理些。

  2. 限制每个关节的旋转角度,越靠近根节点的关节角度越小,使结果更加平滑舒服。

前后向迭代法FABRIK

和CCD不同,FABRIK从关节位移角度求解IK。它会经历若干组前向&逆向IK求解:

  • 前向求解从末端关节开始,让它尽量靠近目标点,然后让其他关节适应变化。
  • 逆向求解从根节点关节开始,由于前向求解的适应变化更改了根节点位置,需要将根节点尽量靠近更改前的位置。

这样反复迭代几次后便能得到IK。

FABRIK应对关节间约束的方法是,在关节点向目标点的垂直平面做投影,然后让关节点尽量靠近投影点。

多目标点IK

实际上目标点不止有一个,例如攀岩时目标点是四肢。

如果使用上面的普通CCD和普通FABRIK求解,会导致关节来回摆动。实际上CCD和FABRIK也是有对多目标点的处理方法,待我补充TODO。

常用算法

雅可比矩阵求解

雅可比矩阵常用于向量运算,给定函数fx和x的取值集合,那么它们的雅可比矩阵就是fx和所有x取值一阶导的集合。

关节移动微分的求解如下,需要知道关节旋转角度的微分。

可以利用雅可比矩阵求解移动角度微分,用移动角度微分正向求解移动微分,然后进而计算新的移动角度微分以逼近目标点。

其他方法

此外还有其他方法,比如基于物理的算法,PBD和XPBD。

挑战

IK还面临以下问题:

研究热点

IK的研究热点如下:

添加混合和IK后的动画管线

表情动画

理论基础

面部肌肉

表情由复杂的面部肌肉系统产生:

表情编码系统

早期电影行业为所有表情编码,为游戏行业的表情系统奠定基础,不同AU可以自由组合。

苹果公司则对表情编码系统做了简化,总结出28个核心表情编码。

于是游戏行业只需做出这些表情动画,然后进行混合就行。但要注意的是,当两个表情混合时,张嘴+不张嘴会线性插值出半张嘴的表情,出错了。这是将整张脸的表情存储起来导致的。

方法

形变动画

因此有了形变动画,它不存储整张脸的信息,而只存储表情形变的顶点偏移信息。形变动画的数据存储和计算量随着面部信息的提升而提升。

骨骼动画

此外,对于眼珠转动以及一些夸张的表情,则需要用到骨骼动画。

形变动画和骨骼动画也是捏脸系统的基础。

UV贴图表情动画

对于非真实感风格的游戏,则可以用2D贴图做表情动画,效果也很不错。

肌肉模型动画

现在也有人在研究如何用肌肉模拟表情动画,结果很真实。

应用—Metahuman

虚幻引擎的metahuman则是表情动画应用的集大成者,十分真实。

动画重定向

为每个角色单独指定一套动画显然是不合理的,因此需要动画重定向技术(Animation Retargeting)将同一套动画应用到不同人物上。这需要将源角色的源动画重定向到目标角色的目标动画上。这个过程通常用其他软件离线进行。

做法

忽略源关节和目标关节的偏移

对于源关节和目标关节间的偏移,我们选择忽略他们。

保持原有的绑定姿势

如果动画里存储的是关节的绝对信息,那么未经处理直接重定向过来会影响目标角色原有的绑定姿势,需要处理一下。或者让动画存储关节的相对信息,例如相对旋转等。

通过尾椎骨高度进行微调

有时动画重定向会给目标角色带来高度偏移问题,可以通过相似三角形法则,将两角色尾椎骨和地面连线,走一段路后按比例计算,微调目标角色的偏移。

进行转换

在重定向后用IK锁死脚

还需要在重定向后用IK锁死脚,例如下图中,使用左边作为源,右边两个为目标,重定向源动画后发现双脚位置不对,需要用IK将双脚锁在地上。

不同骨骼的重定向

有时候会碰见具有不同骨骼层次结构的重定向,这需要一些算法来解决。

容易解法

一种容易的方法是,找寻骨骼间的映射关系,然后逐关节进行简单映射。这是英伟达Omniverse系统的解法。

未解决的问题

  • 角色自穿模问题:将一个体型小的角色动画重定向到体型大的角色后,大角色可能会出现穿模。
  • 语义问题:例如鼓掌动画,手应该接触,但有时候重定向后手不会接触。
  • 重定向后角色是否看起来自然。

参考资料

  • GAMES104 (boomingtech.com)