当今的大多数游戏都围绕某些角色展开 - 通常是人类或类人角色,有时是动物或外星人。 角色的独特之处在于他们需要以流畅且有机的方式移动。 引擎中的角色动画系统负责向角色注入自然的运动。
角色动画的发展
自《大金刚》以来,角色动画技术经历了漫长的发展过程。 最初,游戏使用非常简单的技术来产生逼真的动作。 随着游戏硬件的改进,可以实时应用更先进的技术。 让我们了解一下游戏引擎中最常用的 3 种动画技术。
所有游戏动画技术的前身都是传统动画或者手绘动画。 这种技术被用在最早的卡通动画中。 该动画的运动是通过快速连续显示一系列静态图片(称为帧)来产生的。 实时三维渲染可以想象为传统动画的电子形式,不断地向观众展示一系列静止的全屏图像,营造运动感。
赛璐珞动画
Cel动画是传统动画的一种。 赛璐珞是一种可以在上面绘画的透明塑料片。 通过将一系列动画单元放置在固定的手绘背景上,您可以创建运动,而无需重复绘制静态背景。
赛璐珞动画的电子版是一种称为精灵动画的技术。 所谓精灵,其实就是在不扰乱背景的情况下,叠加在全屏背景图片上的小位图。 它通常由专门的图形硬件绘制。 因此,精灵对于二维游戏动画就像赛璐珞对于传统动画一样。 精灵是2D游戏时代最重要的技术。 下图展示了一组广为人知且广泛使用的精灵位图。 这组帧的设计即使重复播放也能显得流畅 - 该动画称为循环动画。 这组动画用现在的说法可以称为跑步循环游戏引擎结构,因为它是用来展示角色跑步的。 角色通常具有多组循环动画周期,包括多个空闲周期、行走周期和运行周期。
刚性分层动画
自从3D图形技术出现以来,精灵技术已经开始失去吸引力。 《毁灭战士》使用了类似精灵的动画系统。 游戏中的怪物只是面向相机的四边形,每个四边形都附有一系列纹理位图(这种纹理称为动画纹理)来营造运动感。 这种技术至今仍用于低分辨率或远处的物体,例如体育场内的人群或背景中战斗的数千名士兵。 然而,对于三维图形的高质量前景角色,需要进一步的角色动画方法。
最初实现三维角色动画的方法称为刚性分层动画。 在这种方法中,角色是由一堆刚性部件建模的。 人形角色通常分为骨盆、躯干、上臂、下臂、大腿、小腿、手和脚。 脚和头。 这些刚性部分以分层方式相互约束,类似于哺乳动物的关节连接骨骼的方式。 这允许角色自然移动。 例如,当您移动上臂时,您的下臂和手也会随之移动。 一般的层次结构将以骨盆为根,躯干和大腿为其直系后代,其他部分的连接如下:
刚性分层技术的最大问题是角色的身体会在关节处产生难看的“裂缝”,如图11.2所示。 对于确实由刚性部件制成的机器人和机器来说,刚性分层动画可以很好地协同工作,但对于“有血有肉”的角色,当你仔细观察时就会出现问题。
皮肤动画
随着游戏硬件的功能变得越来越强大,一种称为蒙皮动画的技术出现了。
在蒙皮动画中,骨骼是由刚性“骨头”构造而成,这与刚性层动画相同。 但是,这些刚性组件不会被渲染,并且始终处于隐藏状态。 称为蒙皮的光滑三角形网格绑定到骨骼游戏引擎结构,其顶点跟踪关节的运动。 皮肤上的每个顶点都可以加权到多个关节,因此皮肤会随着关节的移动而自然拉伸。
骨骼与姿势
骨架由刚性的关节分层结构组成。 在游戏行业中,术语“关节”和“骨骼”经常互换使用,但术语“骨骼”实际上用词不当。 从技术上来说,关节是可以直接控制的物体,而骨骼只是关节之间的空间。 以下图选择的手关节为例。 它是单个关节,但因为它连接到两个关节,lowerarm_l和index_01_l,所以看起来这个关节连接到两个骨头。 游戏引擎不关心骨骼,只关心关节。 因此,当我们听到“骨头”时,99% 的情况下我们实际上指的是关节。
关节存储自己的位置、旋转和缩放数据,因此关节数据相当于变换数据。
姿势是所有关节变换的集合。 动画资源(动画资源与动画管线的关系)
3D引擎的动画系统需要解决一个问题,即如何输出手势? 大多数引擎使用的解决方案是动画管道。 说起管线UI界面,大家最熟悉的应该就是渲染管线了。
事实上,动画管线和渲染管线类似,都有输入和输出逻辑。 渲染管线的输入是几何图元,着色器处理后的输出是像素。 动画管道的输入是动画资源,经过采样、混合和后处理后的输出是姿势。 它们的区别在于渲染管线的进程相对固定,顶点着色必须在片段着色之前; 动画流水线中的流程并不是固定的,可以根据需要任意安排采样、混合、后处理的步骤。
UE4的动画管线是一个动画蓝图。 下图是一个典型的动画蓝图。 有采样、融合和IK后处理。
我们了解了骨骼蒙皮动画的原理以及动画管道机制。 接下来回到正题,UE4是如何封装各类动画资源的。 连续姿势的集合——序列
单独的静态姿势无法使角色移动,连续姿势的集合可以赋予我们的角色生命。 在UE中,这种包含连续姿势集合的资源称为Anim Sequence。 它是最基本的资源类型,大部分是通过外部 DCC 工具生成和导入的。
下图中,9个角色的移动姿势组合成一个Sequence
序列姿势采样
顺序结构图
Sequence是Pose的封装
1.骨架轨道
在 Sequence 对 Pose 的采样逻辑中,每个骨骼都是一个采样轨迹。 每个采样轨道都会按照时间偏移量采样对应帧的Transform数据。 所有采样的Transform数据被组合成Pose数据。
2. 步进插补类型和线性插补类型的区别
播放时产生的时间偏移一般不会正好落在关键帧上,因此我们需要使用插值来处理这种情况。 首先我们需要通过时间偏移来确定前后两帧。 确定后,UE提供两种方式进行插值。
如下图所示,时间偏移落在6-7中间。 如果插值类型为step,则采样结果为第6帧; 如果是线性的,采样结果就是6和7的插值结果。
序列拼接——复合
UE在Sequence的基础上,提供了可以拼接成Sequence的资源——Composite。 但请注意,Composite 仅拼接序列; 它不提供任何混合功能。
如下图所示,两个序列生硬地拼接在一起。
复合体的姿势采样
复合结构图
Segment是Sequence的封装
Track是对Segment的封装
Composite是对Track的封装
1.动画片段(Segment)
Segment是对Sequence的一层封装。 Segment保存了Sequence的引用,向上层提供Sequence采样功能。
2. 动画轨迹(Track)
Track是Composite和Segment之间的中间层。 Track保存了一个Segment列表,并且可以有多个Segment。 同时,Track也作为Composite的一个属性,为Composite提供采样功能。 Track通过时间偏移定位到对应的Segment,然后进行采样。
可分段多轨合成—蒙太奇
有了拼接,还有分裂吗? 一些! Montage——Composite的增强版,不仅具有Composite的轨道功能(可以拼接Sequence); 它还可以分割曲目。 不仅如此,与Composite只能有一个轨道相比,Montage可以同时有多个轨道。 它只是Composite的加强版和加强版。
不过,与Composite相比,Montage有着非常明显的区别。 也就是说,Montaeg 无法直接在动画蓝图中采样。 相反,Montage只能通过Blueprint脚本或代码来调用播放,然后在Animation Blueprint中对Montage中的轨迹进行采样。
蒙太奇姿势采样
Montage结构图
SlotTrack 是 Track 的封装
Montage 是 Composite 的封装
1.老虎机动画轨道(SlotTrack)
SlotTrack是对Track的一层封装。 每个 Montage 可以有多个 SlotTrack。 有点难理解,我举个例子。
FPS游戏中有一个装弹动作。 根据您是站立还是蹲伏,重新加载动作可能会有所不同。 这时可以在Reload Montage中创建2个SlotTrack,并填写对应的Sequence。 然后根据动画蓝图中当前的蹲类型采样对应的SlotTrack。
2. 时隙组(Group)
UE提供了Group的概念来管理Slots。 这里需要注意的是,Montage 中的 Slot 必须属于同一个 Group。 此外,一个组目前只能播放一个蒙太奇。
3. 部分
Setction用于封装Montage的分割功能。 Montage的播放并不是整个片段的播放。 我们可以在调用播放的时候选择对应的Section。 并且在编辑时可以设置某个片段是否循环播放。
离散姿势的集合——PoseAsset
存在连续的姿态集资源Sequence,UE还提供离散的姿态集资源——PoseAsset。 顾名思义,该资源存储离散姿势。 我们可以对蓝图中指定的 Pose 进行加权采样。
PoseAsset 的姿势采样
PoseAsset结构图
PoseAsset是对Poser的封装
1. 重量取样
当权重值为0时,采样的Pose就是参考的初始Pose。 当权重值为1时,采样的Pose就是PoseAseet中的目标Pose。 权重值在0-1之间,根据权重值混合参考Pose和目标Pose。
Sequence的融合—BlendSpace
UE不仅提供Sequence拼接和分裂,还提供Sequence融合。 该资源可以大大降低动画蓝图的复杂度,将部分融合工作从蓝图中拆分到资源中。 比如下图中人物的位移和倾斜就可以通过BlendSpace来实现。
混合空间采样
BlendSpace结构图
1. 采样轴(X、Y)
一维采样轴
2D采样轴
轴数据示例
BlendSpace可以设置采样轴的数量,一维或者二维,不提供三维。 并且我们可以设置采样轴的取值范围和网格数。
2. 采样列表(SequenceList)
通过采样轴,生成一系列网格点。 通过网格点我们可以排列出对应的Sequence。
3. 取样流程
这部分会很无聊。 。 。
采样点相加 三角网格点权重计算
下图展示了每个网格点的采样三角形信息和权重信息。 它描述了每个点对哪个采样三角形的影响以及三角形每个点的权重。
X, Y; //某个格子区间内的坐标
GridElements; //该格子的格子点列表
for (Element in GridElements) //遍历格子点
{
ElementWeight; //采样点在该格子点的权重
for (i in [0,3)) //遍历格子点的三角形顶点
{
Weight = Element.Weight[i] * ElementWeight //采样动画的最终权重
Anim = Element.Indices[i] //采样动画
Samples.Add(Anim, Weight) //将三角形采样点添加到采样序列中
}
}
// 合并重复的采样动画,以及剔除权重过小的采样动画
目标偏移
AimOffset继承了BendSpace,两者几乎是等价的。
封装的艺术
Pose封装了关节变换的数据。 Sequence封装了连续Pose的插值采样。 后续的复合资源都是基于Sequence构建的。 Composite和Sequence都继承自SequenceBase,但Composite封装了对Sequence容器进行采样的逻辑Montage和Composite。 两者都继承自CompositeBase3D植物,但Montage封装了Section和Slot的逻辑。 BelndSpace相对独立。 它只保存Sequence列表,封装了Sequence列表融合采样的逻辑。 PoseAsset封装了离散Pose的加权采样。参考文献 游戏引擎结构【美】贾森·格雷戈里(Jason Gregory) 动画章节 动画序列动画 复合动画 MontagePose AssetBlend Space虚幻引擎4 动画系统介绍 UE4动画系统源码分析 虚幻引擎学习路径:动画模块基础知识