9.动画树IK和表情动画
9.1 动画混合
动画混合简介
在游戏引擎中,动画是由一个个动画片段(Animation Clip)组成的。当需要从一个Clip切换到另一个Clip时,如果直接切换播放,会产生生硬和不自然的视觉效果。此时需要对两个Clip进行动画混合(Animation Blending)以实现平滑过渡。
动画混合的本质:当游戏中有数百甚至上千个动画素材时,系统不是依次播放它们,也不是随机播放,而是按照特定规则,根据Gameplay需求将多个动画素材混合(Blend)在一起。动画混合是动画系统最重要的底层技术。
案例:从行走到奔跑
通过一个典型案例说明动画混合的必要性。假设游戏中角色行走速度为1.5米/秒,奔跑速度为3.0米/秒。随着角色速度的提升,需要将其动画从行走切换为奔跑。
问题提出:如果为每个速度都制作一个动画片段,从1.5米/秒到3.0米/秒之间需要制作大量包含中间速度段的动画片段。这在制作成本和资源管理上都是不现实的。

简单切换的问题:如果只是设置一个速度阈值进行切换(比如速度超过2.25米/秒就切换到跑步动画),会出现明显的动画跳变:

无混合的直接切换会导致角色动作突然变化,而混合后能实现自然的过渡。
解决方案:通过线性插值(LERP)对两个动画片段进行混合,可以实现平滑的过渡效果。这是动画Blending最基础的原理和典型应用。动画混合的核心目标是实现无极变速——让角色能够在任意速度之间平滑过渡,而不需要为每个速度都制作单独的动画。
混合运算:线性插值(LERP)
实现动画混合需要对骨骼的姿态进行插值。与关键帧插值不同,动画混合不仅需要考虑同一组动画关键帧之间的插值,还要考虑不同组动画不同关键帧的插值。

关键区别:
- 关键帧插值:在一个动画Clip内部,在帧与帧之间进行插值
- 动画混合插值:在不同的动画Clip之间,各取一帧进行插值
理解这一区别至关重要,因为所有的动画Blending都是在多个Clips之间进行插值。
对于每个关节(Joint),无论其平移、缩放还是旋转(旋转是最常见的变换),都需要进行插值。对于旋转,可以使用NLERP(归一化线性插值)或SLERP(球面线性插值)等方法。
计算混合权重
计算插值权重时,根据当前角色运动的速度选择两个相邻动作的关键帧。两个动作的权重即为对速度进行线性插值的权重。

权重计算公式:
假设:
speed_current:当前速度speed₁:Clip1的播放速度(如行走速度1.5 m/s)speed₂:Clip2的播放速度(如奔跑速度3.0 m/s)weight₁:Clip1的计算权重weight₂:Clip2的计算权重
则权重计算公式为:
[
weight_1 = \frac{speed_{current} - speed_2}{speed_1 - speed_2}
]
[
weight_2 = \frac{speed_{current} - speed_1}{speed_2 - speed_1}
]
约束条件:必须保证 weight₁ + weight₂ = 1,即两个权重的和等于1。
工作原理:当速度逐渐增加时,weight₁从1逐渐过渡到0,weight₂从0逐渐过渡到1。这是一个线性插值过程:根据当前速度更接近哪个速度值,相应动画的权重就更大。
对齐混合时间轴
进行动画混合时,有一个容易被忽视的问题:时间轴对齐(Timeline Alignment)。
问题的根源:行走和奔跑的步频不同。奔跑时步频相对较快,行走时步频相对较慢。这两个动画在时间上并不同步。
核心问题:在插值时,如何确定使用奔跑的哪一帧和行走的哪一帧?这是动画Blending系统中的一个基本问题,但在实现初期容易被忽视。
解决方案:动画制作时需要满足以下要求:
- 循环动画:循环动画必须保证第一帧与最后一帧保持一致,确保循环播放时无缝衔接
- 相同的肢体运动频率:如果走路动画是左右脚各迈一次,奔跑动画也必须是左右脚各迈一次
- 脚落地时间一致:脚落地的时间需要大致对齐
满足这些条件后,两个循环动画的时间轴才能对齐。时间轴对齐后,插值能够保证:
- 时间为0时,脚部都未抬起
- 0.25时,左脚踢到空中
- 0.5时,左脚落地
- 0.75时,右脚踢到空中
- 1.0时,右脚落地,重新开始循环
时间轴对齐公式:

假设:
length_current:当前混合后的长度Δt:当前混合空间的delta timeΔt₁:Clip1的delta timeΔt₂:Clip2的delta timelength₁:Clip1的长度length₂:Clip2的长度
则:
[
length_{current} = \frac{speed_1 \times weight_1 \times length_1 + speed_2 \times weight_2 \times length_2}{speed_{current}}
]
[
\Delta t_1 = \frac{length_1 \times \Delta t}{length_{current}}
]
[
\Delta t_2 = \frac{length_2 \times \Delta t}{length_{current}}
]
通过将不同长度的动画片段映射到统一的ratio空间(0到1),实现时间轴的同步对齐。时间轴对齐(Timeline Alignment)是动画混合的基础。
滑步问题
动画混合看似简单直观,但如果对基础概念理解不够准确,容易产生各种Bug。
滑步现象:如果时间轴对齐处理不当,或者速度与插值关系不合理,角色会出现滑步(Ice Skating)现象,即脚部在地面上滑动。
产生原因:
- 速度与权重之间的关系不合理
- 步进速度与动画播放速度未正确配合
视觉效果对比:
- 正常行走:通过正确的时间轴对齐和权重计算,角色能够正常行走,脚部与地面接触自然
- 滑步:如果时间轴对齐不正确,角色会出现滑步现象,脚部在地面上滑动而不自然
滑步是动画混合中必须解决的问题。只有正确处理好时间轴对齐和权重计算,才能获得自然的动画混合效果。
9.2 混合空间
基础的动画混合技术解决了两个动画片段之间的平滑过渡问题。但在实际游戏中,角色的运动往往更加复杂:角色可能从多个角度向前移动,同时改变移动方向和速度。为了处理这种复杂的运动需求,需要引入更强大的混合技术——混合空间(Blend Space)。
一维混合空间
一维混合空间(1D Blend Space)通过一个参数对动画进行混合。在Unity中,典型的应用场景是角色运动:当速度为0时播放idle动画;当速度在0-1时,动画逐渐由idle切换到walk;当速度在1-6时,动画逐渐由walk切换到run。
从简单到复杂:基础的动画混合使用两个动画片段(walk和run)进行混合。实际上,混合空间可以扩展到多个采样点,实现更精细的控制。
案例:定向移动
考虑一个典型的应用场景:角色具有向前走、向左走、向右走三个动画片段。在游戏中,角色需要根据输入在左右方向之间平滑过渡。通过一维混合空间,可以在左右之间进行插值,根据参数值选择三个动画的混合权重。

通过一个参数b(blend parameter)控制三个动画片段(左平移、正向、右平移)的混合。当b在-90到0之间时,在右平移和正向之间插值;当b在0到90之间时,在正向和左平移之间插值。
关键特性:
采样点数量不固定:一维混合空间支持两个、三个、四个甚至更多个采样点。例如,可以添加”往左边慢移动”、”左边快移动”、”站在中间直接往前走”、”往右边慢移动”、”往右边快移动”等五个采样动画。
采样点分布可以不均匀:动画Clip在轴上的分布并不要求均匀。在动画动作变化较小的区域(如正常行走),采样点可以稀疏分布;在动作变化较大的区域(如侧向移动),采样点需要密集分布以捕捉细节。
循环要求:所有参与混合空间的动画Clip必须保持一致的循环属性——要么全部循环,要么全部不循环。混合循环和非循环动画会导致时间轴对齐问题,产生不自然的视觉效果。
这就是一维混合空间的概念:通过一个参数控制多个动画片段的混合,实现角色在单一维度上的连续动画变化。
二维混合空间
问题提出:一维混合空间只能处理单一维度的变化(如速度或方向)。但在实际游戏中,角色往往需要同时改变移动方向和速度。例如,角色可以以不同速度向前、向左、向右移动,甚至可以往斜前方移动。
解决方案:二维混合空间(2D Blend Space)通过两个参数对动画进行混合,能够同时处理速度和方向两个维度的变化。

二维混合空间可以同时处理移动方向和速度的变化。
工作原理:二维混合空间通过将两个一维混合空间正交组合实现。一个维度是速度(Speed),另一个维度是方向(Direction)。
- 速度轴:从idle(0.0)到walk再到run(3.0)
- 方向轴:从-90度(左)到0度(正向)再到90度(右)
在二维混合空间中,每个采样点对应一个动画素材。比如:
- 底部中心:idle(静止)
- 中间行:walk(正向)、leftward(左平移)、rightward(右平移)
- 顶部行:run(正向)、leftward_fast(左快速平移)、right_fast(右快速平移)
插值方法:对骨骼动画进行插值时,根据角色运动的状态在两个方向上分别进行线性插值。首先在水平方向(方向轴)上进行插值,得到两个中间结果;然后在垂直方向(速度轴)上进行插值,得到最终结果。
采样点分布特性:实际应用中,动画素材在采样空间中的分布往往是不均匀的。例如,当角色从走到跑时,如果加上横侧向移动,会很快进入侧向跑状态。由于侧向跑时身体难以保持平衡,速度超过阈值时必须切换到跑的动画,否则视觉效果不真实。因此,动画师会根据动作变化的特点,在需要精细表达的区域放置更多采样点。
Delaunay三角剖分
问题提出:当动画师为角色的平面运动建立了多个不同的预设clip时(例如七八个动画),直接对所有动画进行插值计算量过大。如果每次混合时都要将所有动画blend在一起,性能开销会显著增加。
解决方案:利用Delaunay三角剖分(Delaunay Triangulation)对平面进行划分,可以高效地选择需要混合的动画子集。

工作原理:
三角剖分:根据二维空间中所有动画采样点的位置,生成这个空间的三角形划分。Delaunay三角剖分是一个数学方法,它确保生成的三角形尽可能接近等边三角形,避免出现过于狭长的三角形。
选择三角形:当角色在任何一个速度和方向上时,就确定了二维空间一个唯一的点。系统会选择包含这个点的三角形(即临近的三个动画clips)。
重心坐标插值:使用重心坐标(Barycentric Coordinates)的方法在这三个顶点(三个动画的Clips)里面进行插值。
优势:通过Delaunay三角剖分,系统只需要对三个动画进行混合,而不是所有动画,大大降低了计算量。同时,无论角色以什么速度、什么朝向运动,都能获得平滑自然的动画效果。
这就是完整的2D混合空间的实现。混合空间技术使得艺术家只需要制作有限数量的角色行为动画,就能在游戏引擎中实现流畅的角色运动效果。
骨骼遮罩混合
问题提出:考虑一个典型场景:角色需要在不同姿态下(站立、蹲下、行走等)执行相同的动作(如鼓掌)。如果为每个姿态都制作完整的动画,工作量巨大且不现实。
核心矛盾:无法为每个姿态都制作完整的动画。通常只能制作上半身的动作动画(如鼓掌),但下半身的行为会根据姿态而变化。
解决方案:骨骼遮罩混合(Skeleton Masked Blending)通过对骨骼进行遮罩,实现不同动画对不同骨骼区域的控制。通过设置mask,可以让某些动画只应用到上半身,某些动画只应用到下半身。


工作原理:
定义遮罩:设置一个mask来标记混合动画时需要考虑角色的哪些骨骼。整个骨骼的所有混合百分比集合
{βⱼ} | j=0 to N-1有时被称为混合遮罩b。分别应用:
- 下半身应用”蹲下”姿态动画
- 上半身应用”鼓掌”动作动画
优势:
- 数据量更小:由于只有部分关节参与动画,动画数据量显著减小
- 计算量下降:应用到skeleton时,只需处理部分骨骼,计算量大幅降低
- 自由组合:可以将两种或更多动画在角色身上进行灵活组合

骨骼遮罩混合(Skeleton Mask Blending)使得角色无论处于什么姿态、什么位置,都能正确执行鼓掌动作。
加法混合
问题提出:在某些场景中,角色需要在执行基础动作(如鼓掌)的同时,头部需要朝向特定目标(如摄像机)并执行额外动作(如点头)。这要求动画系统能够在不影响基础动作的前提下,叠加额外的相对位姿变化。
核心需求:角色具有点头动画(向前点头、向左点头、向右点头),同时需要支持多种坐姿,手部执行鼓掌动作,头部朝向目标并执行点头动作。
解决方案:加法混合(Additive Blending)引入了一种称为差异片段的新型动画,它代表了两个常规动画片段之间的差异。

工作原理:
差异片段:将差异片段添加到常规片段中以生成新片段。差异剪辑片段可以添加到常规动画剪辑中,从而在角色的姿态和动作上产生有趣的变化。
相对位姿:角色动作只与关节相对姿态有关,而与绝对姿态无关。以点头动画为例,角色在点头时可以有不同的朝向,但在录制动画时只需要一套统一的动画。
叠加应用:在实际进行动画混合时,根据角色当前的姿态叠加上相对位姿。在已有的skeleton结构基础上,叠加额外的旋转、translation或scale变换,实现动画的叠加效果。

加法混合使得多个角色在不同姿态下都能朝向目标执行点头动作。
注意事项:使用这种additive blending技术时需要额外注意角色的姿态,尤其要避免角色关节的姿态超过最大值的情况。
骨骼异常结果:加法混合更容易产生异常的骨骼结果。例如,角色执行转身动作时,脖子已经旋转了一定角度,如果再叠加一个扭头动作,脖子的旋转角度可能超过其物理限制,导致角色姿态不自然。
因此,使用additive blending时需要谨慎处理,在规划角色运动时,需要避免过度叠加动画,防止某些关节的行为超出合理范围。
动画混合技术概览

动画混合技术的完整体系包括:
- 一维混合空间:基于单一输入值混合姿态
- 二维混合空间:基于两个输入值混合姿势,使用三角混合
- 遮罩混合:对部分骨骼进行混合
- 叠加混合:在已有动画基础上叠加差异片段
总结:通过这四个核心算法(一维/二维混合空间、骨骼遮罩混合、加法混合),可以将数百甚至上千个动画按照游戏逻辑需求进行灵活组合和叠加。这些技术已经足以支撑一些简单游戏的动画系统实现。对于不需要完整艺术家工具链的游戏项目,这四个算法基本能够满足动画混合的需求。
9.3 动作状态机
混合空间技术解决了动画的同步混合问题,但在实际游戏中,许多动作是状态化的,无法通过简单的插值实现。例如,跳跃动作需要根据离地高度进行动态调整,角色跳多高、多久能落地都不是动画能够预先确定的。这时需要引入动作状态机(Action State Machine, ASM)来管理状态化的动画切换。
为什么需要动作状态机
问题提出:在很多情况下,角色的动作不能直接通过对动画进行插值来获得。以跳跃为例,角色的跳跃动作可以划分为起跳、浮空以及落地三个不同状态。这些状态之间存在依赖关系,无法通过直接插值的方式来计算角色当前的动作。
典型案例:跳跃动画
考虑一个典型场景:角色从不同高度的台阶上跳下。虽然起跳高度可能相同,但由于台阶深度未知,无法预先确定落地时间。如果使用单一的跳跃动画,无法适应这种动态变化。

跳跃动作被分解为三个状态:
- 起跳状态(jump begin):播放起跳动画
- 浮空状态(in the air loop):循环播放空中动画,直到检测到落地
- 落地状态(jump end):播放落地动画
状态切换逻辑:
- 当玩家按下跳跃键时,从idle状态切换到jump begin
- 当起跳动画播放完成后,切换到in the air loop(循环播放)
- 当检测到角色即将落地时,切换到jump end
- 落地动画播放完成后,返回idle状态
这种状态化的设计使得跳跃动画能够根据游戏中的实际物理状态动态调整,而不是依赖固定的动画时长。
动作状态机的结构
核心概念:将角色的动作和状态视为图上的节点,角色的运动等价于在不同节点之间进行状态转换。这种模型称为动作状态机(Action State Machine, ASM)。

ASM的核心元素:
节点(Node):ASM由节点和转换关系构成。节点类型包括:
- 混合空间节点(Blend Space Node):可以将整个混合空间打包成一个节点
- 片段节点(Clip Node):单个动画片段
转换关系(Transition):定义节点之间的切换条件和方式
数据结构定义:
class ActionStateMachineClipNode
{
AnimationClip m_clip;
bool m_is_loop;
};
class ActionStateMachineBlendSpaceNode
{
BlendSpace m_blend_space;
bool m_is_loop;
};
节点特性:
- 节点可以是一个简单的动画片段,也可以是复杂的混合空间
- 节点可以嵌套动画蓝图,实现复杂的动画逻辑
- 节点最终输出一个动画pose(姿态)
状态转换:当满足特定条件时,系统会从状态A(node A)切换到状态B(node B)。转换条件可能包含多个条件,需要全部满足才能触发转换。
状态过渡方式
ASM内部的动画切换有两种主要方式:平滑过渡(Smooth Transition)和冻结过渡(Frozen Transition)。

过渡类型定义:
class ActionStateMachineTransition
{
int m_source_node_index;
int m_target_node_index;
};
class ActionStateMachineTransitionWithCrossFade
{
int m_source_node_index;
int m_target_node_index;
float m_duration;
Curve m_curve;
};
平滑过渡(Smooth Transition):
- 使用动画混合插值方法逐步从一个动画过渡到另一个动画
- 动画A的贡献量逐渐减少,动画B的贡献量逐渐增加
- 适用于两个循环动画之间的过渡,要求时间轴保持同步
冻结过渡(Frozen Transition):
- 将当前动画暂停在某一帧
- 新动画基于冻结帧逐渐混合进来
- 适用于某些动作切换场景,避免继续播放原动画导致的不自然效果
例如,从跑步切换到起跳时,使用smooth transition可能会让人感觉角色在空中还在试图跑步,而使用frozen transition会让角色先停下来再起跳,视觉效果更自然。
交叉淡入淡出

平滑过渡(Smooth Transition):
- 限制条件:两段剪辑必须为循环动画,且其时间轴需保持同步
- 工作原理:在过渡期间(tstart到tend),Clip A逐渐淡出,Clip B逐渐淡入
- 权重变化:β值从0线性增加到1
冻结过渡(Freeze Transition):
- 工作原理:Clip A在tstart时刻冻结,然后Clip B逐渐混合进来
- 优势:不要求循环动画,适用于非循环动画之间的过渡
平滑过渡通常产生最自然的视觉效果。
交叉淡入淡出曲线
过渡过程中的权重变化可以通过不同的曲线来控制,产生不同的视觉效果。

常用曲线类型:
- Linear(线性):权重均匀变化,是最简单的过渡方式
- Ease In/Out(缓入缓出):使用Cubic或Bézier曲线,开始和结束时变化较慢,中间变化较快
- 其他曲线:Sin、Quad、Cubic、Quart、Quint、Expo、Circ等,每种都有In、Out、InOut三种变体
实际应用:
- 动画系统中最常用的是线性插值和缓入缓出(Ease In/Out)
- 其他曲线类型在动画系统中使用较少,但在粒子系统等其他引擎模块中会用到
- 曲线选择通常由动画师根据视觉效果需求决定
虚幻引擎中的动画状态机
动作状态机技术已经广泛应用于各种游戏引擎中。虚幻引擎实现了完整的ASM系统,允许开发者自定义角色的动画状态和切换条件。

状态机结构:
- 状态(State):输出姿态的蓝图图表,可以是简单的动画片段,也可以是复杂的混合空间
- 过渡(Transition):控制状态切换时机与混合方式,可以设置多个过渡条件
过渡配置:
- 优先级顺序(Priority Order):当多个过渡条件同时满足时,按优先级执行
- 双向过渡(Bidirectional):是否允许双向切换
- 混合逻辑(Blend Logic):标准混合或其他混合方式
- 过渡持续时间(Duration):通常设置为0.2秒左右
- 混合模式(Mode):Hermite Cubic等插值模式
- 自定义混合曲线(Custom Blend Curve):可以选择不同的过渡曲线
状态节点内部:
- 每个状态节点内部可以包含复杂的动画蓝图
- 可以嵌套使用1D或2D混合空间
- 支持根据输入参数(如Speed、Direction)动态混合动画
虚幻引擎的动画系统设计灵活,支持自由嵌套和组合,其图标和交互设计符合设计师的直觉,是动画系统设计的优秀参考。
分层式动作状态机
在实际游戏中表达一个角色时,最经典的设计是分层式动作状态机(Layered ASM),将角色身体的不同部位单独设计成状态机。

分层设计原理:
- 角色的身体不同部位能够同时执行不同、独立或半独立的动作
- 每一层控制特定的骨骼区域,通过遮罩技术实现独立控制
典型分层结构:
- 上半身层:控制受击、攻击等动作
- 下半身层:根据玩家控制,处理跑、跳、走等移动动作
- 头部层:独立控制头部动作
- 受击层:处理角色受击反应
技术实现:
- 使用LERP(线性插值)和Additive(加法混合)两种方式
- Gesture Layer使用LERP或Additive混合
- Variation Layer使用Additive混合
- Base Layer提供基础动画
实际应用案例:
以《鬼泣5》为例,角色的打击感之所以出色,是因为:
- 下半身的跳跃、移动动作与上半身的攻击动作可以独立控制
- 不同层的状态机可以同时运行,产生丰富的组合效果
- 角色动作更加灵活自然,不会显得僵硬
分层式ASM是最经典的设计,在现代游戏引擎中仍然广泛应用。通过多层状态机的组合,能够在游戏中表达出活灵活现的角色行为。
9.4 动画混合树
在ASM的基础上,现代游戏引擎引入了动画混合树(Animation Blend Tree)的概念。动画混合树可以理解为一棵表达式树,它按照指定的计算规则对不同的动画资源进行混合,从而产生新的动画。
混合树的概念
混合树将分层异步状态机(ASM)的结构与操作组织为树状结构,受表达式树启发,便于动画师理解和操作。

核心特性:
- 非终端节点与终端节点:混合树由终端节点(叶节点)和非终端节点组成
- 节点运算结果:每个非终端节点的运算结果都是一个位姿(pose)
- 递归结构:计算节点中可以包含更复杂的计算过程,甚至是小型的动画树
使用动画树描述动画混合的优势在于,可以基于简单的树状结构描述复杂的动画混合过程。例如,layered ASM可以看做是不同动画资源在相应层级上进行混合的结果。
线性插值混合节点
线性插值混合节点是混合树中的基本非终端节点,用于将两个输入姿势以权重β进行LERP插值,生成一个输出姿势。

二元线性插值节点:
- 输入:Clip A和Clip B两个姿势源
- 权重:β(0到1之间的值)
- 输出:混合后的姿势
扩展LERP节点:
通常扩展为支持多输入处理,例如三元/四元线性插值节点。扩展版本可以同时处理多个输入姿势(如Clip A、B、C、D),根据混合参数b在多个姿势之间进行插值。
基于动画树的结构,可以在LERP的基础上定义更复杂的动画混合插值计算。
叠加混合节点
叠加混合节点是混合树中的基础非终端节点,用于将第二个输入姿态(通常为差异姿态)按权重β叠加到第一个输入姿态上。

工作原理:
- 输入1:Clip A(基础姿势)
- 输入2:Diff Clip B(差异姿势,通常为相对变化量)
- 权重:β(控制叠加强度)
- 输出:叠加后的最终姿势
叠加混合节点对应前面介绍的additive blending技术,通过该节点可以在原始动作上叠加一个新的动作,实现更灵活的动画组合。
在混合树中表达分层ASM
混合树可以用来描述分层ASM期望的最终姿态,将不同层级的ASM输出通过树状结构进行组合。

时间t的分层ASM:
在特定时间点t,不同层级的ASM(如ASM B、F、H、K)可能处于不同的状态,每个ASM输出一个姿势。
混合树结构:
- 终端节点:ASM B、ASM F、ASM H、ASM K作为输入
- 非终端节点:使用加法混合节点(+)和LERP节点进行组合
- 组合逻辑:ASM B和F先相加,结果再与ASM H相加,最后与ASM K进行线性插值
这种树状结构使得复杂的多层动画混合过程变得清晰和易于管理。
混合树节点类型
混合树节点可以分为两大类:终端节点和非终端节点。

终端节点(叶节点):
- Fragment(片段):单个动画片段
- Blend Space(混合空间):1D或2D混合空间
- ASM:动作状态机的输出
非终端节点(非叶节点):
- 二元LERP混合节点:两个输入的线性插值
- 三元(三角)LERP混合节点:三个输入的三角插值
- 二元加法混合节点:两个输入的叠加混合
在虚幻引擎中,这些节点类型都有对应的实现,如”Blend Poses by bool”、”Blend Poses by int”、”Layered blend per bone”等。
虚幻引擎中的动画蓝图
虚幻引擎实现了完整的动画混合树功能,称为动画蓝图(Animation Blueprint)。

动画蓝图特性:
- 输出最终姿态的蓝图图表:通过节点图的方式组织动画混合逻辑
- 输入源:以剪辑姿势或ASM(动画状态机)的结果作为输入
- 混合方法:通过不同方法混合输入姿态
典型结构:
- 输入层:Locomotion State Machine、UpperBody State Machine等状态机输出
- 混合层:Layered blend per bone等混合节点
- 输出层:Output Pose AnimGraph
游戏开发者和设计师可以利用大量的计算节点来自定义角色的不同行为。
混合树控制参数
动画混合树的核心在于使用控制变量(Control Parameters)来改变输出动画的结果。

控制参数系统:
节点搜索:为高层代码提供一种在树中查找混合节点的方法
命名变量:允许为各个控制参数分配名称。控制代码可以通过名称查找控制参数,以便调整其值
控制结构:一个简单的数据结构,包含角色所有控制参数。混合树中的节点会连接到特定的控制参数
控制变量通常来源于游戏的玩法系统。当控制变量发生改变时,动画树会根据自身定义的规则动态地调整动画混合的比例以及使用的动画资源。
虚幻引擎动画蓝图控制
在虚幻引擎中,动画蓝图中作为成员的命名变量可以通过蓝图更新,并可在混合树(Blend Tree)内部任意位置使用。

使用控制参数:
- 在Blendspace Player等节点中,Speed和Direction等控制参数作为输入
- 这些参数控制混合空间中的动画选择和混合比例
更新控制参数:
- 通过Event Blueprint Update Animation事件每帧更新
- 从游戏逻辑(如BP_DeathPlayer)获取当前状态值
- 使用SET Direction和SET Speed节点更新动画蓝图中的变量
虚幻引擎使用variable作为动画树的控制变量调整不同动画之间的混合比例。此外,还使用event作为资源切换的信号,当动画树接收到某个event后会调整自身的动画资源实现角色动画状态的改变。
虚幻5动画树示例

虚幻引擎5的动画树示例展示了完整的动画混合流程:
主要部分:
- Locomotion:基础移动动画处理
- Upperbody/lowerbody split:上下半身分离混合
- TurnInPlace:原地转向处理,防止脚部滑动
- Procedural fixup:程序化修正,如IK(反向运动学)处理
技术特点:
- 使用Cached Pose提高性能
- 通过Layered Blend per Bone实现精确的骨骼控制
- 使用Control Rig进行程序化动画调整
- 支持Additive动画叠加
动画混合树远比那些经典节点(如事件节点、计算/逻辑节点以及特殊混合与流程控制节点)复杂得多。这种递归的计算结构为设计师提供了更高的设计自由度,能够实现复杂的动画效果。
9.5 IK技术
前面介绍的动画系统都是直接利用骨骼和关节的运动学公式来驱动角色的动作,这种方式称为正向运动学(Forward Kinematics, FK)。但在很多情况下,需要考虑游戏场景对角色肢体的约束,并利用这些约束求出合适的骨骼关节姿态,这种动画技术称为反向运动学(Inverse Kinematics, IK)。
IK与FK的基本概念
IK在游戏中应用广泛,例如角色在崎岖不平的地面上行走时,需要根据地面起伏调整脚部位置。

基本概念:
- 末端执行器(End Effector):预期将被移动到目标位置的骨骼
- 逆向运动学(IK):利用运动学方程确定机械臂的关节参数,使末端执行器移动到期望位置
- 正向运动学(FK):利用机器人的运动学方程,根据指定的关节参数值计算末端执行器的位置
核心区别:
- FK:从Root节点开始,逐步正向计算每个节点位置,以符合最终效果
- IK:在最终效果骨骼确定的情况下,反推其他骨骼变动情况
IK在游戏中使用较为常见,因为游戏场景中的约束(如地面高度、物体位置)通常是已知的,而需要计算的是关节姿态。
为什么需要IK
问题提出:某些动画难以通过常规方式处理。例如,角色伸手拿杯子、登上不同高度的阶梯,这类动画的特点是:在动画结束时需要特定骨骼移动到指定位置。

典型场景:角色在不平坦的地面上行走时,如何让脚部触达地面?如果使用固定动画,脚部可能会悬空或陷入地面。
直观思路:为每一步调整脚部位置,使脚部始终与地面接触。

通过IK技术,可以根据地面高度动态调整腿部关节角度,确保脚部正确触地。
双骨骼IK(Two-Bone IK)
双骨骼IK是指只有两个骨骼限制的IK,常见于人物行走在地面的效果。两个骨骼是指与地面接触的点以及大腿根部,通过几何关系可以简单计算腿的弯曲角度。

工作原理:
- 利用骨骼长度和场景约束构造三角形
- 使用余弦定理(Law of Cosines)计算关节角度
- 公式:
cos(θ) = (a² + c² - b²) / (2ac)
二维空间求解:在二维平面上,给定两个骨骼长度a、b和目标距离c,可以唯一确定关节角度θ。
三维空间的挑战:在三维空间中,基于上述方法会得到无穷多组解,因此需要引入额外约束来保证解的唯一性。

解决方案:通过参考向量确定最终姿态。

在三维空间中,通过指定一个参考向量(Reference Vector),可以唯一确定腿部的朝向,从而得到唯一的解。
更复杂的IK场景
在实际游戏中,IK的应用场景更加复杂多样。

常见应用场景:
- 注视反向运动学(Gaze IK):控制角色头部和视线朝向目标
- 手部逆向运动学(Hand IK):控制手部精确抓取或接触物体
- 足部反向动力学(Foot IK):控制脚部在不平坦地形上的精确放置
- 全身反向运动学(Full-body IK):控制整个身体姿态以适应复杂环境
多关节IK的复杂性
当有多条链的IK处理时,情况变得极其复杂。

主要难点:
- 计算成本:实时求解高维非线性函数,计算开销巨大
- 解的不确定性:可能有多解、唯一解或无解
- 目标可达性:需要检查目标是否在关节链的可达范围内

检查目标可达性:在求解前需要判断目标是否在关节链的可达范围内。如果目标超出范围,IK求解将失败或产生不自然的结果。
关节约束
角色的不同关节往往具有不同类型的约束。在进行求解时需要考虑这些约束,否则会出现角色动作过于扭曲的状况。

人体骨骼约束类型:
- 铰链关节(Hinge):如肘部、膝盖,只能在一个平面内旋转
- 球窝关节(Ball-and-socket):如肩部、髋部,可以在多个方向旋转
- 枢轴关节(Pivot):如颈部,主要进行旋转
- 鞍状关节(Saddle):如拇指根部,允许两个方向的运动
- 髁状关节(Condyloid):如腕部,允许两个平面的运动
- 滑动关节(Gliding):如踝部,允许滑动运动

约束的重要性:在游戏开发中,需要认真对待约束条件。忽略关节约束会导致角色动作不自然,甚至出现物理上不可能的姿态。
启发式算法
在三维空间中求解带约束的IK问题非常复杂,目前还没有通用的算法来进行实时求解。在现代游戏引擎中,一般通过启发式算法进行近似求解。

为何使用启发式算法:
- 关节与约束条件过多,难以用解析方法求解
基本思路:
- 通过牺牲最优性、准确性、精确度或完整性来换取速度,以更快更高效的方式解决问题
近似方法特点:
- 无法保证全局最优性
- 通常采用迭代方式并设置最大限制次数
CCD算法
CCD(Cyclic Coordinate Descent,循环坐标下降法)是目前游戏引擎中求解IK问题最主流的算法。

原理:
- 从关节到关节,将末端执行器尽可能旋转至目标位置,在方向空间中解决逆向运动学问题
算法流程:
- 在已知最终首末两端位置情况下,从终点位置依次连接末端骨骼到起始骨骼
- 旋转所连接的骨骼,使得末端骨骼处于两者连线上
- 最后尝试将末端骨骼移动至指定位置
可达性:
- 算法可在特定迭代次数后停止,以避免无法到达目标的问题
约束处理:
- 允许角度限制,通过每次迭代后进行检查
优化CCD算法
标准CCD算法可以进一步优化,以生成更自然、视觉效果更舒适的姿态。

优化方法1:容差区域
为每根骨骼的目标添加容差区域:
- 每根骨骼在容差区域内停止旋转并转向下一根骨骼
- 有助于生成更加自然、视觉效果更舒适的姿态
相比标准CCD,优化后的算法能够更均匀地分配旋转角度,避免某些关节过度旋转。
优化方法2:欠阻尼角度缩放

使用欠阻尼角度缩放:
- 每个关节仅向目标移动微小幅度,并将运动量分散到多根骨骼上
- 减少关节的突变变化,为角色运动生成更平滑自然的姿态
这种方法通过限制每次迭代的旋转幅度,确保关节变化更加平滑,避免突然的姿态跳变。
FABRIK算法
FABRIK(Forward And Backward Reaching Inverse Kinematics,前向后向递推逆运动学)是另一种经典的IK求解算法。

原理:
- 不同于在方向空间中求解,该算法在位置空间中解决逆向运动学问题
算法流程:
- 依次使用FR(Forward Reaching)和BR(Backward Reaching)迭代计算骨骼位置,直到达到理想效果
- FR:强制末端骨骼移动到指定位置,再依次移动其他骨骼保证骨骼长度不变
- BR:从首端骨骼开始处理
可达性:
- 算法可在达到一定迭代次数后停止,以避免无法到达目标的问题
带约束的FABRIK
FABRIK可以很容易地考虑关节约束的问题。

重新定位:
- 可以在每一步通过获取结果方向并强制其保持在有效范围内来执行关节限制
3D约束:
- 通过将3D约束映射到2D平面,可以简化约束处理
- 在2D中寻找重新定位目标,然后映射回3D空间
当关节的转动角度存在约束时,只需要把关节转到约束内垂直于目标的方向即可。
多重末端效应器
上面的算法解决了单条链的IK问题,但在复杂模型中往往存在多个终端点的情况。例如角色攀岩时,需要将四肢附着在墙壁上。

问题提出:
- 可能导致目标之间的冲突,这些目标无法同时实现
- 各个附着点的链条相互影响
处理方式:
- 可采用优先级或加权策略

多末端效应器逆向运动学:
- 若需移动共享骨骼,最后更新的末端效应器将获得优先级,其他骨骼则会被牵引偏离
- 通过设置优先级或权重,可以控制多个末端效应器的相对重要性
雅可比矩阵IK
雅可比矩阵(Jacobian Matrix)是行业内处理多末端效应器IK问题的通用方法。

定义:
- 在向量微积分中,多元向量值函数的雅可比矩阵是其所有一阶偏导数组成的矩阵
假设:
f(x)是一个m维向量值函数x是一个n维输入向量
则雅可比矩阵J为m×n矩阵,其中每个元素J_ij = ∂f_i/∂x_j。

使用雅可比矩阵表示关节旋转:
对于每个关节的旋转,末端执行器的位置变化可以表示为:
- 仅旋转关节0:
Δs = u₀ × (s - p₀) Δθ₀ - 仅旋转关节1:
Δs = u₁ × (s - p₁) Δθ₁ - 仅旋转关节2:
Δs = u₂ × (s - p₂) Δθ₂
其中u_i是旋转轴,p_i是关节位置,Δθ_i是角度变化。

多末端效应器的雅可比矩阵:
对于m个末端效应器和n个关节的系统,雅可比矩阵J为:
[
J = \begin{bmatrix}
\frac{\partial s_1}{\partial \theta_1} & \frac{\partial s_1}{\partial \theta_2} & \cdots & \frac{\partial s_1}{\partial \theta_n} \
\frac{\partial s_2}{\partial \theta_1} & \frac{\partial s_2}{\partial \theta_2} & \cdots & \frac{\partial s_2}{\partial \theta_n} \
\vdots & \vdots & \ddots & \vdots \
\frac{\partial s_m}{\partial \theta_1} & \frac{\partial s_m}{\partial \theta_2} & \cdots & \frac{\partial s_m}{\partial \theta_n}
\end{bmatrix}
]
其中:
m:末端效应器的数量n:关节数量
逐步逼近目标
雅可比矩阵IK通过迭代方式逐步逼近目标位置。

反馈控制流程:
- 误差计算:计算当前末端执行器位置
s与目标位置t的误差Δs - 计算J⁻¹:计算雅可比矩阵的逆矩阵,将位置误差转换为关节角度变化
Δθ - 更新关节角度:
new θ = current θ + Δθ - 关节控制:将新的关节角度应用到物理关节
- 正向运动学:通过正向运动学计算新的末端执行器位置
new s - 反馈循环:重复上述过程,直到误差足够小
这种方法通过闭环反馈控制,能够稳定地收敛到目标位置。
其他IK解决方案
除了上面介绍的几种经典算法外,目前游戏业界对于IK问题也提出了一些其他方法进行处理。

基于物理的方法:
- 更自然
- 通常在没有优化的情况下需要大量计算
PBD(基于位置的动力学):
- 区别于传统的基于物理的方法
- 更优的视觉表现
- 较低的计算成本
UE5中的全身逆向运动学:
- 使用XPBD(扩展型基于位置的动力学)
- 提供更自然的全身IK效果
IK仍面临的挑战
总体来看,IK仍然是非常复杂的问题,在近几年得到了人们越来越多的关注。

主要挑战:
- 自碰撞避免:防止角色身体部位相互穿透
- 带移动预测的逆向运动学:预测角色未来位置,提前调整姿态
- 自然人类行为:生成符合人类运动习惯的姿态
- 数据驱动与深度学习:利用机器学习方法改进IK求解
IK研究领域发展

IK技术从1977年至今经历了多个发展阶段:
- 解析方法(Analytical):1980年代
- 雅可比方法(Jacobian):1977年至今,持续发展
- 牛顿方法(Newton):1980-1990年代
- 数据驱动方法(Data-Driven):2000年后快速发展
- 启发式方法(Heuristic):1990年代至今
- 混合方法(Hybrid):1990年代至今
近年来,数据驱动和深度学习方法在IK领域得到了越来越多的关注。
IK在动画管线中的整合
需要注意的是,IK也需要整合到动画管线中作为后处理来调整骨骼和关节的姿态。

更新动画管线:融合与反向动力学技术:
CPU阶段:
- Extract(Local Space):从多个动画片段提取局部姿态
- Blend(Model Space):混合多个局部姿态,生成模型空间姿态
- Post-processing(World Space):转换为世界空间姿态,应用IK调整
GPU阶段:
4. Skinning(World Space):使用最终的世界空间姿态生成蒙皮矩阵调色板,计算网格顶点位置
IK作为后处理步骤,在动画混合完成后对姿态进行微调,确保角色与环境正确交互。
9.6 面部动画

面部肌肉特点:
- 43块肌肉:面部共有43块肌肉
- 形态、力度和运动方式各异:不同肌肉具有不同的形态、力度和运动方式
- 协同作用:这些肌肉协同作用以形成表情
主要面部肌肉:
- 额肌(Occipitofrontalis):控制眉毛和额头的运动
- 皱眉肌(Corrugator supercilii):使眉毛聚拢
- 眼轮匝肌(Orbicularis oculi):控制眼睑闭合
- 口轮匝肌(Orbicularis oris):控制嘴唇运动
- 颊肌(Buccinator):控制脸颊和咀嚼运动
高精度要求
面部动画对精度要求极高,细微差别会带来截然不同的效果。

细微差别的影响:
- 自主/被迫:同样的表情,自主产生和被迫产生在视觉上可能完全不同
- 自然/刻意:自然表情和刻意表情之间存在微妙但重要的差异
- 相反的表情:有时会表现出截然相反的表情
微表情对于面部动画的精度要求极高。人的面部表情很难表达,细微的变化就可能表达出完全相反的含义。骨骼动画虽然也可以处理面部表情,但即便是最简单的表情也需要花费大量的时间处理。
面部动作编码系统(FACS)
得益于电影工业对面部表情的探索,人们发现只需要面部五官进行组合就可以表现出不同的表情。这种表达表情的方式称为FACS(Facial Action Coding System,面部动作编码系统)。

FACS定义:
- FACS是一种根据面部外观对人类面部运动进行分类的系统
- 一共包含46个基本动作单元(Action Units, AU)
动作单元分类:
- 上半脸动作单元:包括眉毛、眼睑、脸颊等部位的动作
- 下半脸动作单元:包括鼻子、嘴唇、下巴、下颌等部位的动作
每个动作单元对应一个特定的面部肌肉运动,通过组合不同的动作单元可以表达各种复杂的表情。
动作单元组合
一个表情可以被视为某些基本动作的组合。通过组合不同的动作单元,可以创造出丰富的面部表情。

组合示例:
- AU 4(眉毛下压肌):使眉毛聚拢并下压
- AU 5(上眼睑提升肌):使上眼睑提升
- AU 4+5组合:同时应用AU 4和AU 5,可以创造出惊讶、恐惧或紧张的表情
通过组合不同的动作单元,可以表达出从简单到复杂的各种表情。FACS在基础表情库的基础上进行组合,表达其他表情。
28个核心动作单元
在实际应用中,由于面部的对称性,实际上在制作表情动画时只需要一半左右的单元就可以表达不同的表情。

核心动作单元:
- 苹果公司提取了28个核心动作单元(AUs)
- 23个对称动作单元被划分为两个基本动作(左右各一个)
- 基础动作集会根据动画制作需求而变化
常见动作单元:
- 上半脸:Inner brow raiser、Outer brow raiser、Brow lowerer、Upper lid raiser、Cheek raiser、Lid tightener等
- 下半脸:Nose wrinkler、Upper lip raiser、Lip corner puller、Lip corner depressor、Chin raiser、Lip pucker等
关键姿态混合
基于FACS可以制作不同的表情动画。在表情动画中,一般直接使用面部的网格而不是骨骼关节系统来描述表情,不过动画插值的思想和骨骼动画是一致的。

关键姿态混合(Key Pose Blending):
- 一组关键姿势,基于逐顶点动画的变体
- 通过线性插值混合不同的关键姿态:
wA × Pose A + wB × Pose B = Blended Pose - 其中
wA和wB是权重值,控制每个关键姿态的贡献
人脸表情动画的本质是对几个关键Pose做插值运算,然后用顶点动画实现动画效果。
简单混合的问题
进行表情混合时需要注意,直接对面部进行混合往往会得到错误的结果。

问题分析:
- 人脸在表达不同表情时一般只会用到一小部分面部肌肉
- 直接对表情进行混合容易造成整个面部发生运动
- 例如,将”张嘴”和”闭眼”直接混合,可能会导致不自然的结果
解决方案:
- 存储一个基本表情(中性表情)
- 利用前面介绍过的additive blending技术对表情进行叠加
- 只存储与中性姿势不同的顶点偏移量,而不是完整的网格
FACS在形变动画中
在形变动画(Blend Shape Animation)中,创建动作单元(AU)关键姿势时,仅存储与中性姿势不同的顶点,使用加法混合。

中性面顶点偏移:
- 每个动作单元只存储相对于中性表情的顶点偏移量
- 通过颜色梯度可视化顶点偏移的程度:
- 红色/橙色:最大偏移
- 黄色:中等偏移
- 蓝色:较小偏移
- 灰色:无偏移
这种方法可以高效地存储和混合多个表情,避免存储完整的网格数据。
形变目标动画
形变目标动画(Morph Target Animation)是面部动画的常用技术。

工作原理:
- 面部动画通过关键姿态之间的变形来实现
- 每个关键姿态对应一个特定的表情
- 通过滑块控制不同表情的混合权重
关键姿态示例:
- Pucker(撅嘴):控制嘴唇的撅起程度
- Smile(微笑):控制嘴角上扬的程度
- Frown(皱眉):控制嘴角下压的程度
通过调整这些参数,可以创造出各种自然的面部表情。
复杂面部骨骼
除了使用网格变形外,也有一些使用骨骼来表达面部表情的实践。

复杂面部骨骼:
- 使用密集的骨骼网络控制面部变形
- 骨骼从下巴/下颌区域向面部各个部位辐射
- 通过控制骨骼的旋转和位移来驱动面部变形
使用骨骼动画的优势:
- 比较适合表达面部比较大的变形
- 例如眼球的转动、嘴巴张开
- 游戏中常见的捏脸系统也使用骨骼动画
UV纹理面部动画
除了使用网格或骨骼外,很多游戏也会使用二维纹理图像来实现表情动画。

UV纹理面部动画:
- 通过在简单头部模型上应用一系列纹理贴图来实现
- 这种方法在很多卡通渲染的游戏中有着大量的应用
应用案例:
- 《动物森友会:新视野》:使用简单的纹理切换实现表情变化
- 《塞尔达传说:旷野之息》:在卡通风格的角色中使用纹理动画
这种方法计算成本低,适合风格化的游戏。
肌肉模型动画
目前在学术界还出现了通过直接对人的面部肌肉进行建模然后实现表情动画的方法。

肌肉模型动画:
- 基于物理模拟的方式更为精确,但也更为复杂
- 三层结构:皮肤层、肌肉层、骨骼层
- 肌肉控制:肌肉控制着面部的大部分区域
- 附着点移动:附着点的移动距离由肌肉收缩程度决定
- 皮肤响应:皮肤所使用的模型将决定插入点肌肉周围区域如何响应
特点:
- 尽管这种方法还没有大规模应用在游戏业界
- 它的计算需求也远高于传统方法
- 但它却可以实现更加逼真的角色表情
现代面部动画工具
现代游戏引擎提供了强大的面部动画工具,使得创建逼真的面部表情变得更加容易。

Metahuman:
- Epic Games开发的数字人类创建工具
- 提供高度逼真的面部模型和动画系统
- 支持实时渲染和高质量的面部表情
主要功能:
- Blend:混合不同的面部特征
- Skin:皮肤材质和细节调整
- Eyes:眼睛的详细控制
- Hair:头发和眉毛系统
- Body:身体类型和服装
这些工具大大简化了面部动画的制作流程,使得开发者能够创建出更加真实和生动的角色表情。
9.7 动画重定向
动画重定向(Animation Retargeting)是游戏行业中的重要技术。在动画制作中,动画师往往只会对同一个动作进行一次建模,而在游戏中,设计师则希望把这个动作应用到各种不同的角色中。这种把一组动作从一个角色迁移到另一个角色的技术称为动画重定向。
角色间共享动画
动画重定向允许动画在不同角色间复用,大大节省了动画师的工作量。

动画重定向的优势:
- 节省工作量:允许动画在不同角色间复用,节省动画师工作量
- 降低成本:将动作捕捉动画适配到不同角色,降低制作成本
- 提高效率:一次制作的动作可以应用到多个角色上
通过动画重定向,同一个动作可以应用到不同体型、不同风格的角色上,从机器人到人类,从卡通角色到写实角色。
基本术语
在动画重定向中,需要理解几个基本术语。

核心术语:
- 源角色(Source Character):已经绑定好动作的模型
- 目标角色(Target Character):需要施加动画的角色
- 源动画(Source Animation):源角色的动画数据,包含骨骼结构和姿态信息
- 目标动画(Target Animation):重定向后应用到目标角色上的动画
动画重定向的过程就是将源角色的动画数据转换为适合目标角色的动画数据。
基本重定向算法
动画重定向最直接的做法是把对应骨骼和关节的动作直接复制过去。考虑到源角色和目标角色骨骼之间位置的差异,一般需要对关节姿态进行一定的补偿。

偏移量问题:
- 源骨骼与目标骨骼在重定向姿态下可能存在偏移量
- 这个偏移量是源关节向量和目标关节向量之间的角度差
- 在基本重定向算法中,这个偏移量通常被忽略
考虑到不同角色之间姿态的差异,在进行重定向时可以只施加关节的相对运动。这种做法会得到更加自然以及符合人直觉的动画效果。
绑定姿势问题
在不同绑定姿势中保持朝向是一个重要的挑战。

问题分析:
- 当源角色和目标角色具有不同的绑定姿势时,直接重定向可能导致目标角色看起来很奇怪
- 例如,目标角色的头部可能被严重扭曲,出现不自然的姿态
解决方案:
- 需要保持关节的朝向一致性
- 通过适当的旋转补偿来确保重定向后的姿态自然
处理轨迹
动画重定向需要分别处理不同类型的动画轨迹。

轨迹处理规则:
- 旋转轨迹来源于源动画:保持动画中的关节朝向
- 位移轨迹来源于目标骨骼:保持目标骨骼的比例
- 缩放轨迹源自源动画:保持动画中的缩放比例
综合这些规则,就得到了动画重定向最基本的算法:处理关节旋转时考虑关节的相对旋转,处理骨骼的平移时根据目标角色骨骼的实际长度进行补偿,对于缩放的情况则直接按照比例进行缩放。这样就可以把源角色的动作迁移到目标角色身上。
骨盆高度对齐
在实际工程中,由于源角色和目标角色本身骨骼的差异,强行迁移动作容易造成目标角色悬空的现象。

通过骨盆高度对齐运动:
- 角色的移动:通常由位移曲线或运动系统在运行时控制
- 位移曲线提取:位移曲线是从动画中的骨盆姿态提取而来
- 比例缩放:需要根据骨盆的比例进行缩放
问题与解决:
- 问题:悬空的双脚没有移动缩放,导致角色脚部悬空
- 解决:通过运动缩放缓解问题,根据骨盆高度调整角色位置,确保脚部接触地面
IK锁定脚部
当骨骼比例差异过大时,即使使用了基本重定向方法,仍然会出现穿帮效果。

问题分析:
- 源骨骼与目标骨骼的腿长比例不同
- 如果大腿保持水平,较长的大腿会导致脚部悬垂
- 较长的胫骨则会造成穿模现象(脚部穿透地面)
IK解决方案:
- 重定向后通过IK锁定脚部
- 使用IK算法确保脚部正确接触地面
- 根据目标骨骼的实际比例调整腿部姿态
例如,同样的蹲在地上的动画,由于大腿与小腿的比例差异,基本重定向方法就会产生穿模,这时就需要使用IK来辅助解决。
不同骨骼层级
目前介绍的重定向方法都假定了源角色和目标角色的骨骼有相同的拓扑结构,但在很多情况下两个角色的骨骼是没有办法做到一一对应的。

骨骼层级差异:
- 源骨骼:可能具有单脊柱结构
- 目标骨骼:可能具有三脊柱结构
- 骨骼层级不同,但功能相似
当骨骼结构相似但不完全相同时,需要更复杂的算法来传递动画。
解决方案
处理不同骨骼层级的方法有很多,一种较为简单的方法是规定骨骼名称相同的进行Retargeting处理。

简易解决方案:
- 通过共享骨骼作为中间层
- 源骨骼 → 共享骨骼 → 目标骨骼
- 将中间没有Retargeting的骨骼归一化
Omniverse中的解决方案:
- 使用关节链的归一化表示
- 通过插值方法将源关节链映射到目标关节链
- 这种方法可以处理更复杂的骨骼层级差异
比较直接的处理方法是利用骨骼和关节的对应关系来对关节运动进行插值,这样就可以把原始骨骼的动作重定向到新的骨骼上。实际上在Omniverse上就使用了类似的方法来处理动画重定向的问题。
Omniverse中的动画重定向
Omniverse提供了强大的动画重定向功能,可以处理各种复杂的场景。

Omniverse的优势:
- 支持不同体型、不同风格的角色
- 可以同时处理多个角色的动画重定向
- 提供实时预览和调整功能
通过Omniverse,可以将同一个动作应用到从小型角色到大型怪物,从人类到机器人的各种角色上。
未解决的问题
动画重定向仍然是一个相对比较复杂的问题,很多时候即使把源角色的动作迁移到目标角色上仍然会出现很多穿模或者相交的问题。

未解决的问题:
- 自网格穿透:角色身体部位之间可能发生穿透
- 自接触约束:例如鼓掌时双手的接触,重定向后可能无法正确接触
- 目标角色的平衡性:重定向后的动画可能影响角色的平衡感
在这种情况下,一般还需要动画师对迁移后的动画进行一些微调。
Morph动画重定向
动画重定向的技术除了可以应用在骨骼上,实际上还可以应用在表情动画上。

Morph动画重定向:
- 不同面部共享相同拓扑结构
- 通过相同的网格拓扑,可以将表情动画从一个角色迁移到另一个角色
- 这种方法适用于面部表情动画的重定向
Morph动画重定向问题
在迁移表情动画时,由于不同模型尺度的差异,有时会出现穿模等诡异的问题。

问题示例:
- 眼睛无法完全闭合:重定向后,角色的眼睛可能无法完全闭合
解决方案:
- 无法闭合:识别出眼睛闭合的问题
- 移动顶点:手动调整眼睑的顶点位置
- 顶点已移动:将上眼睑顶点向下移动
- 平滑处理:对调整后的网格进行平滑处理,确保自然过渡
此时可以对网格施加一些额外的约束来强行获得正确的动画效果。通过手动调整顶点位置和平滑处理,可以解决表情动画重定向中的各种问题。
9.8 总结
本章介绍了现代游戏引擎中动画系统的核心技术和实现方法,涵盖了动画混合、IK技术、面部动画和动画重定向等关键内容。

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com