原文链接:游戏开发入门(五)游戏动画系统_动画指引游戏 开发-CSDN博客
2.动画是关于时间的函数:
- 逐帧动画:随着时间的变化,去改变图片内容,常用于2D角色动画
- 刚体动画:随着时间变化,改变某个刚体的位移(或旋转,缩放),常用于游戏动画录制等
- 顶点动画:随着时间变化,改变模型顶点的位置,可用于简单的模型变换,捏脸,自定义角色等
- 骨骼动画:3D游戏必用,随着时间变化改变骨骼模型关节的旋转,进而驱动骨骼上的蒙皮,用来模拟角色动画
- UV动画:随着时间变化,改变模型上的贴图的UV数据,从而模拟其表面变化的效果,常用于水面的模拟
- 粒子动画:随着时间变化,改变粒子的轨迹与形态,用于加强场景的效果表现。
- 布料动画:随着时间变化,改变顶点或者骨骼关节的位置(本质上是顶点或者骨骼动画),用于模拟如衣服头发飘动的效果
3.骨骼动画的优势:
关节在局部空间运动,只有旋转数据(避免角色身体部分拉长),无论是性能还是表现都很优秀
骨骼动画理解:骨骼动画的变换是基于局部坐标空间系的,比如人体手腕关节在旋转时,他是基于其父关节点(小臂)的空间坐标系下进行变换的,而小臂的旋转又是基于他的父关节点(大臂)的,一直递推到根骨骼。所以,我们在世界坐标空间下更新骨骼动画时,只需要传入根骨骼的坐标(模型原点),对该坐标进行坐标变换,整个骨骼都会跟随这一起变换。
4.粒子动画系统就是我们常见的发光特效,其组成包括一个发射器,一个效果器还有一个销毁器。
发射器可以绑定在某个对象上,随着对象移动,移动的同时发射粒子,效果器作用于发射出来的粒子,可以影响粒子的颜色,明暗,位置等属性。销毁器负责销毁粒子。
5.布料动画采用的原理是弹簧质点模型,可以很好表现诸如头发衣服的飘动效果
6.游戏动画系统主要解决的问题:
- a.管理动画资源,在合适的时间合适的方式去读取合适的动画
- b.完美的更新当前需要表现的动画
- c.输出动画给其他模块去使用
7.动画数据处理模块:
存储了动画每帧(或固定某几帧)的状态与数据,可能是图片、矩阵、多个浮点数等
注:由于存储空间的限制,我们不可能将连续动画所有帧(什么更精细)的数据全部存储下来。所以,美术在制作动画资源的时候只是对关键帧进行制作修改,我们需要也通过对一套动画资源采样来尽可能模拟动画。如果我们只进行逐帧采样,会导致动画不流畅。所以,我们考虑时间采样。时间采样需要解决一个问题,时间是连续的,动画资源是不连续的,所以需要对两个关键帧没有动画的地方处理,这个处理就是插值。插值是游戏制作里面一个非常基础而且重要的技巧。处理动画以外还用于更新摄像机位置,对顶点之间的渲染等。
游戏的互动性决定了动画不能是完整的一大段的,玩家可以随时终止或修改当前播放的动画
8.常见插值:
线性插值,样条线插值
9.什么是帧?
帧的概念在游戏中比较混乱,有时人们可能认为他是时间单位,比如一秒有30帧。但实际上帧是指某个时间点的画面,一秒30帧指的是一秒内能渲染出30张静态的画面数据,帧数越高动画效果越流畅。
10.关于切线空间:
参考一下知乎上的讲解 为什么要有切线空间(Tangent Space),它的作用是什么? - 知乎 (zhihu.com)
11.关于全局时钟与局部时钟的理解:
这是游戏引擎架构的一个例子。我这里做一个更为形象的描述,假如玩家有一个攻击动画一共3帧,NPC有一个受击动画也是3帧。如下图。当玩家在第N帧攻击的时候,播放攻击动画第一帧,但是由于NPC在这一帧已经更新完了,所以NPC接受攻击并播放动画只能在第N+1帧去播放。如果用局部时间,那么在N+1帧更新的时候,他更新的就是受击动画第0帧,然而这时候玩家播放的是攻击动画第二帧。很明显就不匹配了。
如果用全局时间,那么在玩家播放攻击动画的时候,全局时间一直在变化,这时候NPC其实应该开始计时并更新动画(不过在第N帧的时候没有机会更新了)。等到第N+1帧的时候,NPC就会按照全局时间更新,那效果就是与玩家同步的动画了,但是问题是NPC为了与玩家保持一致可能跳过了第一帧动画。
12.IK
视频中神秘海域角色手能够牢牢抓住墙靠的其实就是IK技术。IK全称Inverse kinematics,意思是反向动力。我们通常角色的动画是靠身体根部的关节来驱动的,比如你在移动手臂的时候,是肩的位置开始通过手臂肌肉来完成的。但是这样在游戏中有个问题,我的攻击动画只考虑出拳,正常来说如果前面有障碍我的拳头遇到障碍就会停下来的。在没有任何处理的情况下,这个拳头遇到障碍并不会停下而是穿过去,所以我们需要根据拳头移动过程中遇到的障碍来改变拳头以及手臂的位置,从拳头改变并反向的影响玩家手臂的操作就是IK技术。 关于IK的文章链接:
13.动画复杂性分析:
a.游戏中,玩家可以通过按键迅速改变角色的动作,那各种的动画切换如何处理?
美术在制作动画的时候,不可能任何两个动作都能完美的衔接,所以需要平滑的过渡处理。这里平滑其实就是前面提到的插值,比如从走路切换到跑步时,有一段时间两个动画同时更新,然后根据权重进行处理。根据插值的类型不同,分为普通圆滑过渡(线性,视频中为淡入淡出)与缓入缓出(贝塞尔曲线)两种过渡。
b.角色在移动过程中可能还会有其他动作(如回头,举手),那如何根据参数选择并混合不同的动作?
- 如果角色在某个状态下只有一个动作,那可以直接播放该动画就可以,不过想同时表现两个动画就需要对动画进行混合了。
- 一维线性混合:给一个参数b,根据b的大小确定一个区间。每个区间对应两个动画,在这个区间内根据权重对两个动画进行混合。
- 二维线性混合:一般来说至少需要准备4个动画,由两个参数决定二维平面上的一点,进而对多个动画进行混合。
- 其他混合:三角形二维线性插值混合(对三个片段形成的三角型构建重心坐标方程,这个重心不是我们常说的中线相交的,而是各个点有一定质量,然后求重心)泛华的二维线性插值混合(与三角形重心坐标类似,将多个片段每三个构成一个三角形再去建立重心坐标方程)
- 视频中还提到一个四面体的插值混合,个人觉得这个在动画混合中并不常见,因为一般二维的动画混合足以解决大部分的动画混合问题,三维混合只会增加操作成本。但是对于某些实际应用场景,该方法比较直观,比如空间中的一个顶点,需要通过插值确定他的颜色,这时候可以确定他所在的一个四面体,然后根据四面体四个顶点来插值(利用四面体插值公式)。
c.如何表现动画的多样性?
最简单的办法就是做更多的动画资源,但是这种方法会增加包的大小,而且美术的工作量几乎以指数爆炸的形式增长。
所以我们通过一些常见的办法来处理,如叠加混合。举例子来说,玩家在走路的时候可能会向左右观察,如果做成单个的资源,就要做一个普通走路,向左看走路,向右看走路,如果跑起来的话,又要做一套向左看跑,向右看跑。但是其实玩家在向左看的时候,除了头部以外,几乎没有其他动作,所以我们并不需要做了一个向左看走又做一个向左看跑的动作,只需要向左看的动画。然后,将向左看与走路(跑步)动画叠加混合就可以了。这个与前面b的差别是前面提到的混合是多个动画完全混合,这里的叠加混合属于局部空间混合,不过局部混合属于完全混合的一种,本质上一样的。
另外一种就是,骨骼分部混合。他会对每个关节设置一个混合百分比,然后在制作动画的同时制作一个动画遮罩,在动画播放的时候设置部分关节的遮罩为1,这样就能达到混合效果了。但是,相比前面的叠加混合,骨骼混合属于动作取代,在表现上稍微逊色一些,有时候会造成动画动作不自然。
其他的方法:动画镜像,共享骨骼资源,IK等。
d.如何应对越来越复杂的动画逻辑?
前面基本上描述了动画播放的基本逻辑(动画是时间的函数),但是一个复杂的动画同时还可能需要其他方面逻辑的配合,比如声音,特效,特殊事件等。这些逻辑与动画可能非常紧密的交织在一起,很难拿出某个模块单独处理。所以,动画系统产生了一个动画轨来处理这些逻辑,我们可以把这些逻辑添加到动画某个特定帧的位置,这样基于动作我们就可以做很多的处理。