动画系统的前世今生(一)

掐指一算,五年没更新过我的CSDN账号啦,方向也从人工智能变成了计算机图形学,当然也依旧会关注AI的发展,之前在知乎上写了一些文章[传送门],后续也会逐渐同步到CSDN上~ 这个系列将包含五篇文章,内容来源于王希老师GAMES104课程的动画系统与动画高级技术部分,这是系列的第一篇文章~

动画技术简介

在介绍完渲染系统后,今天将介绍动画系统。相较于渲染系统,动画更加直观,更容易理解。动画也是游戏中最重要的一个系统,所以值得我们不断钻研,发现其中的乐趣。实际上,人类在很早的时代就开始对运动物体充满兴趣,因为我们观察到自然界都是运动的。但人类最早的表达方式只有绘画,所以你可以发现在几万年前,我们先辈画在岩石上的绘画都是动感十足的,包括在先祖的陶器中,你会发现画了一系列人物的动态,而不只是一个静帧。那个时候没有投影技术,但人类先祖脑中想的是一个动起来的世界,所以我们一直在探索这样的一个方法。

直到近代,人类发现一个非常有意思的现象,就是著名的"视觉残留"现象,这也是现代所有显示设备的一个理论基础。当我们看到一个物体,这个物体的影像在眼睛中会残留大概1/24秒。而这是所有电影、电视,包括游戏以及游戏动画的一个基础的理论支撑。因为我们没有办法真正实现自然界中那种连续不断、可以无限细分的动画系统。

这也不得不提早期一个特别有意思的尝试------西洋景,它在以前科学不发达的时候,能用这种方法让大家在投影上看到一个运动的东西,比如一个小人。还有小时候在纸上画的小人动画,实际上这都是现代动画的基础。

那么动画的先驱是什么呢?首先是电影行业,可以这么认为:游戏行业动画的基础理论、基础工具都来自于电影行业。从最早迪士尼动画的2D动画,到早期七八十年代,电影开始将动画生成的虚像和实拍的实像结合到一起。在侏罗纪公园问世时,计算机动画技术已经到了一个非常高的高度。

今天在游戏中实现的动画效果,实际上是在逼近离线渲染,比如阿凡达。当年我看到阿凡达的时候,觉得这是游戏动画未来需要努力的方向。这里也要提到一部电影------Zafari,Zafari 实际上是第一部完全使用游戏引擎实时渲染制作的动画片,这也代表了动画未来的方向。以前我们认为动画是离线的,而如今可以通过实时渲染制作得到。

这些动画技术的底层到底是什么呢?从最早的电影开始,制作过程非常简单,通过一帧、一帧的2D手绘,将其绘制出来。后来发展到用摄像机拍摄演员的动作,在演员身上绑定marker,通过光学方法追踪标记点,恢复出人物动作。一些电影中的人物表现得非常真实、自然,实际上是使用了动捕技术。我相信很多同学看电影幕后的时候都能看到动捕技术,动捕技术也是游戏动画的一个核心基础。

Games 104关注的是游戏引擎,接下来介绍游戏动画,游戏动画的鼻祖依然是电影行业。最早期的动画非常简单,不断翻转、播放图片。波斯王子游戏中的角色看起来非常自然、灵活,但实际上也是通过图片制作出来的。为了制作出逼真的动画,制作者拍摄了波斯王子的弟弟,让其模仿动画中需要的动作,并根据照片将动作绘制出来,成为了游戏中的像素。在那个时代,波斯王子中角色的动作非常自然。即使是基于骨骼的3D动画技术,我们追求的自然感仍来自于真实的人类,而人类对这种自然的真实感非常敏感。另一个需要highlight的游戏是Doom,它看起来是3D游戏,但实际上是通过2D动画实现的。游戏中墙体带给玩家的空间感,是通过图片的变形实现的;而游戏中的开枪动作等,是通过当前相机角度配合一组图片实现的,让玩家感觉自己身处3D环境中,Doom也是游戏动画的鼻祖之一。

进入3D时代后,我们开始有了显卡。在生化危机等游戏中,角色也开始有了动画,但这个时候的动画会存在一些问题:动画中运动的只有骨骼,会显得非常生硬。之后出现的蒙皮动画,会使得角色看起来像真人一样自然。现在的游戏动画越来越真实细腻,既有基于物理的仿真,也有角色非常自然的动画。

提到游戏动画,不得不说它有很多挑战。电影行业中的动画在完成制作后,通常逐帧进行播放。而在游戏动画中,我们不能预设玩家的行为,比如玩家在行走的过程中,突然决定要奔跑,跑的时候突然看到前方有障碍物需要跳跃,跳跃后觉得需要抓住某个物体。所以在游戏世界中,动画需要与gameplay互动,接受来自玩家的输入,同时也受限于游戏环境,比如角色在奔跑过程中撞到障碍物,此时需要播放对应动画,或者角色在走路过程中,突然被怪物抓住或打倒。这些gameplay、物理反馈,如何能够在动画系统中及时反应,表现得非常自然?这是游戏动画系统中,相对于电影,它具有挑战的地方。

另一个挑战从渲染部分一直跟大家提起,游戏引擎中所有的东西都是实时的,everything is real time,无论算法多复杂、高端,永远需要在1/30秒里将它算完。每一个系统,比如前面讲到的绘制,现在讲到的动画,包括游戏逻辑、物理、AI,这所有的东西都要竞争1/30秒,也就是30毫秒。但现代游戏又希望游戏角色越做越新颖,场景越来越宏大,这事实上给动画系统造成了巨大的挑战。因为它的挑战不仅是算力的问题,还包括动画数据本身非常大,需要不断获取数据进行计算。在渲染系统中讲过,当在内存中获取数据时,性能是非常低的。所以这也是游戏引擎中动画系统的一大挑战。所以今天我们会讲的动画压缩技术,实际上也在解决这样的挑战。

第三个挑战是什么呢?实际上随着现代游戏的要求越来越高,我们对角色的自然感和真实度要求也非常高。当动画师在制作动画的时候,一般会预设角色在一个无限延伸的平面上做反复循环的动作。但在游戏中,你会发现角色每时每刻都要接受来自于用户的输入,需要不断地切换动画。

最右边图中展示的是游戏中最火的motion matching技术,它将很多动作融合在一起,使得角色非常鲜活。此外,角色还需要跟环境进行各种符合物理规则的互动,即physic-based animation。当相机距离角色足够靠近的时候,我们可以看到角色的脸,此时会看到人类最敏感的东西------表情。直到现在,表情都是计算机游戏中非常有挑战的部分,想做得很好的话非常困难。我们对真实感也提出了越来越高的要求,因为大家已经习惯于游戏引擎实现的效果能够逼近于电影。而且我们的屏幕越来越大,分辨率从4k变化到8k。未来我们希望能有一个非常high fidelity的虚拟人物站在我们的面前,讲到虚拟人技术的话,其实最核心的就是动画技术。这就是游戏引擎中动画技术的一个核心挑战。

大家不要认为今天的游戏都是3D的,实际上这个星球上最popular的、最赚钱的游戏是2D游戏。其实,2D动画技术也是一个非常重要的技术。接下来,会讲3D动画技术,而在3D动画技术中,会开辟一个专门的章节讲述蒙皮动画真正的实现细节。因为大家提到的3D动画技术,其核心就是蒙皮动画,也是现在游戏中角色的动画。蒙皮动画的原理讲起来非常简单,但当你钻研下去,开始真正写游戏引擎,而不是简单地调用引擎的时候,你会发现其中有很多基础理论、基础数学的问题。

那么我们今天这节课讲的是游戏引擎,所以会跟大家讲一些真正的细节,这些细节是很重要的。很多时候,你以为自己理解了,但在写的时候如果对基础知识掌握不够扎实的话,会写出很多bug。第四部分会讲动画数据的处理,今天课程讲一个非常简单,但又非常实用的东西,就是动画数据的压缩。因为如果今天你要写游戏引擎的话,动画数据是一定要压缩的,否则就会有很多问题。最后会跟大家介绍整个动画生成的pipeline,因为当我们去写游戏引擎的时候,不是只写引擎里面的东西,大概率可能会要写3ds Max、Maya的插件,帮助艺术家把动画转换成你自己引擎所能接受的格式,而这里就要求你对艺术家生产动画素材和数据的流程有所了解。基本上听完今天这节课,你就能做一个完整的动画pipeline。第二节课会跟大家介绍一些相对高端、fancy的技术,也属于现代游戏引擎的标配。比如动画的混合,即如何根据游戏操作逻辑进行各种合理的混合;包括IK技术,即动画与环境间的互动;还有整个复杂的animation pipeline,以及大家喜闻乐见的动画树,它的设计原理、它有哪些节点、它是怎么运作的。

最后会讲两个比较有意思的东西,第一个是怎么去做人面部的动画,你们会发现Facial Animation和普通形体的动画是两套技术体系------两套完全不同的方法论和技术栈。另一个是Animation Retargeting,能否把一个人在走路的动画转移到一个大怪兽上,形成走路的动画。这些技术相对第一节课的技术来讲要难一点,但如果想做一个3A游戏引擎的话,这也属于入门级的一些技术。所以动画两节课会讲一些标准现代游戏引擎里的核心模块,其实还有一些比较前沿的内容,像Motion Matching等,有可能在整个课程上完之后,争取在高级课程中跟大家去讲。大家先在这两节课把动画系统的基础打好,如果将来你想成为一名游戏动画师,或者gameplay的designer,再或者gameplay的programmer,包括你想成为动画方面的专家,这节课的内容与你的相关度非常高。

2D游戏动画技术

精灵动画

2D动画事实上是整个游戏引擎动画的鼻祖,最标准的是精灵动画,也就是Sprite Animation。它的想法非常简单,把游戏里角色整个动作的每一帧记录下来,然后在游戏中循环播放,是不是就是一个很完美的2D动画?其实我们童年的回忆全是这样的2D动画,不知道大家有没有玩过任天堂、小霸王这样的游戏机,上面所有的游戏都是用这样的2D动画技术制作出来的。

这里特别要讲到Super Mario,记得我在第一节课讲过那个时代做游戏不需要游戏引擎,他们真的非常聪明,比如像这只小蘑菇,实际上就是一张图,把它flipping后不断播放,你就感觉到一个小家伙瞪着眼睛向你走过来。所以那个时候真的资源很少,大家做东西还是非常具有想象力的。

精灵动画这样的技术虽然很古老,但在现代游戏引擎中,即使是高端的3D游戏引擎,这个技术也仍然存在。在游戏的很多系统中,比如像Particle System,后面有一节课会专门讲它。粒子系统中产生的爆炸效果,其爆炸出的每一个粒子不是静态的一张图,实际上是一个序列帧,你可以看到烟球慢慢扩散的效果。所以,精灵动画在2D游戏、特效系统中还是被广泛应用的。

Live 2D

但真正的游戏,也就是大家经常氪金的游戏,实际上使用了一种更加高端的2D动画技术,就是这里要着重介绍的Live 2D。我个人还是蛮喜欢这个技术体系的,非常简单,但给艺术家的空间特别大。右侧二次元角色非常鲜活,她就是用一系列图片通过变形、编辑得到的。如果想制作卡牌游戏、二次元游戏,但预算、时间有限,这一部分将是你们最关注的东西了。

Live 2D的想法非常简单,将一个角色上的所有元素,比如头发、眼睛、眉毛变成图元,将这些图元拼在一起,变成一个大资源。对于每个图元进行旋转、缩放以及变形,变形简单来讲就是对图元中的三角形、四边形进行仿射变换,通过上述操作将角色鲜活地表现出来。Live 2D听上去真的有这么强吗?一开始我也觉得它怎么可以做得这么好?包括很多大作,像这种二次元少女风格的游戏都是使用这个技术制作的。

首先对所有图元设置深度,深度可用于表示图元间的层次关系,当它动起来的时候,互相之间不会穿插。其次会为每个元素生成一个控制网格,在这个控制网格上可以随机加入控制点,当对这些点进行移动时,图元会跟着变化。当一个角色表示开心或者不开心时,眉毛会发生变化,用这种简单的技术就可以实现,在二次元中这种表达本身已经非常具有表达力。

在使用Live 2D技术制作动画时,本质上是在每一帧调整上述图元。例如在某一帧中角色眼睛是闭着的,下一帧中角色的头产生移动,再下一帧,角色可能会摇头,以此类推将很多帧K好后,一个非常鲜活的角色就出现了,这就是Live 2D的原理。Live 2D非常符合艺术家的直觉,不需要理解复杂的3D变换、投影等,就能做出一个很棒的游戏。Unity、Unreal,包括我们自己的引擎都会全面支持Live 2D。3D游戏很多时候是技术上复杂,内容上更加真实,但从游戏性角度,2D游戏是真正的王道。

如果大家将来做引擎的话,2D游戏引擎也是很值得大家关注的一个方向。有一些很前沿的引擎,在2D部分做得非常好。我们也看到了一些非常优秀的作品,给你的感觉非常好,这其中有很多有意思的技术在里面。

3D游戏动画技术

在介绍3D动画技术前,先介绍一个概念------ Degree of Freedom ,即自由度。它指的是一个物体有多少个自由度,就可以在多少个维度去变化。

对于一个刚体,其在整个三维空间运动的自由度为6个自由度。因为它有平移的3个自由度,可以沿着x、y、z三个方向去平移,这是3 DoF。刚体还可以沿着三个轴旋转,分别以x、y、z轴为中心进行旋转。所以整个三维空间的刚体,其自由度为6。整个游戏动画的核心是基于自由度的表达,也是对刚体运动的一个表达。

3D游戏动画中最基础的是基于层次结构的刚体动画,它非常像小时候看的皮影戏,把角色的每个关节做成可动的。当移动关节时,整个角色就可以运动起来。实际上,关节本身有一个树状结构,即Hierarchy。刚体动画存在一个问题,当网格模型与骨骼进行绑定时,骨骼发生变动,会导致网格模型彼此穿插。就像小时候看到的皮影戏,它各个关节之间会发生穿插。

在很多3A游戏中都使用了一种技术------Per-vertex Animation,即顶点动画。如果在游戏中,旗帜类型物体表现得特别好,有可能使用了基于物理的动画或者顶点动画。如果使用骨骼表达风吹布料的效果,需要放置多根骨骼。相比之下可直接存储每个顶点位置随时间的变化,通常会存储两张纹理图:第一张纹理图的横向轴对应着每一个顶点,如果顶点数为100万,横轴也为100万,假设动画是100帧,竖向轴对应着每一帧逐顶点的偏移量。由于顶点发生变化,表面法向也会产生变化,直接使用顶点位置计算法线可能出现问题。从效率的角度出发,将顶点法向信息存储到第二张纹理图中。通常使用物理引擎进行仿真,将顶点动画信息存储到贴图中,在引擎中就能够展现出非常真实的旗帜效果。

此外,有另一种类型的顶点动画------Morph Animation,其主要被用于人脸动画、捏脸系统中。它在每个顶点上有影响权重,在每个Key Frame对Key Pose进行混合,并在每帧之间进行插值。相信很多小伙伴喜欢玩游戏中的捏脸系统,我一直认为捏脸系统是游戏的本体,大家拿到游戏愿意花三、四个小时去捏脸。捏脸系统是不是可以通过骨骼来驱动?是的,但如果当变形过大时,脸上的五官看起来就不自然了,而通过在不同Morph Target间进行插值可以实现自然的脸部变化。

在游戏中出现最多的对象是人、动画角色,人和动物最大的特点是他们表面都有一层皮肤,但它不会随着身体的运动而发生皮肤间的自我穿插。游戏中通常会使用3D蒙皮动画技术实现类似的动画效果,其核心思想是每个顶点受到多根骨骼的影响,这样能够保证当一个对象去运动时,它是水密性的,即皮肤间不会互相穿插。它比早期刚体的骨骼动画做得要好,是现代游戏引擎中最常见的动画模型。

其实蒙皮动画技术在2D动画中也有广泛应用,因为2D动画面临着同样一个问题:如果使用骨骼驱动图片运动,图片间彼此会产生穿插。所有角色看起来就像机器人一样,如果使用同样原理将蒙皮动画的方法运用到2D角色中,当你看到人在运动的时候,整个身体会相对自然地去变形。它们的技术原理是一致的,3D蒙皮动画中的数学运算在2D中也是完全起作用的。

最后一种动画形式是Physics-based Animation,比如一个角色一旦受击或者死亡时,他会进入一个Ragdoll状态,也就是中文中的布娃娃系统。早期的时候,布娃娃系统把人设计得像沙袋一样,但现在布娃娃系统既有设计师设计的Animation感觉,又有整个人摔在地上的感觉。此外,还有关于物理的模拟。基于物理模拟的动画被使用最多的地方其实是衣料,我相信现在很多小伙伴在玩游戏的时候,会非常在意角色身上的衣料表达得好不好?但衣料模拟其实是游戏动画或者游戏物理中最难的一部分,包括流体的模拟。

在游戏中,如何保证角色的手永远能够抓到一点?这时就需要使用IK技术,IK的全称叫反向动力学,它指的是给定一个点,角色如何运动看上去才最自然。简单来讲,比如在人的面前放一个苹果,人去抓苹果是不需要训练的,天然就会的。但在游戏中如何让这个动作一气呵成,实际上是非常复杂的。大家可能会奇怪,为什么计算机会比人笨?但仔细观察一下小朋友,当他在只有0到6个月的时候,在他面前放一个物体,他其实是抓不住的,他需要练习很久才能准确抓到苹果。所以对于人的话,有可能是使用Deep Learning的方法经过长达以年为单位的训练,练就了准确的抓取能力。但今天在游戏中,用IK系统也能模拟出人这样的能力。

上面主要介绍的是动画系统在Runtime时的方法,另外一个更重要的是Animation Creation,即如何创造动画。传统方法有两种,一种是动画师在编辑器中手K动画,其中的K是指通过Key Frame,即关键帧创作动画。还有一种是Motion Capture,即动捕,动捕技术目前在电影、游戏中已经使用得非常广泛。

相关推荐
天人合一peng4 小时前
unity 生成标记根据背景色变色为明显的颜色
unity·游戏引擎
魔士于安4 小时前
Unity 超市总动员 超市收银台 超市货架 超市购物手推车 超市常见商品
游戏·unity·游戏引擎·贴图·模型
CandyU24 小时前
Unity —— 数据持久化
unity·游戏引擎
zh路西法4 小时前
【Unity实现Oneshot胶卷显形】游戏窗口化与Win32API的使用
游戏·unity·游戏引擎
迪捷软件5 小时前
显控系统虚拟仿真的工程化路径
游戏引擎·cocos2d
XX風7 小时前
单缓冲区渲染导致闪烁的具体技术原因是什么?
图形渲染
Swift社区10 小时前
传统游戏引擎 vs 鸿蒙 System 架构
架构·游戏引擎·harmonyos
mxwin1 天前
Unity Shader 半透明物体为什么不能写入深度缓冲?
unity·游戏引擎·shader
dgaf1 天前
DX12 快速教程(17) —— 立体图标与合并渲染
c语言·c++·3d·图形渲染·d3d12
晚枫歌F1 天前
三层时间轮的实现
网络·unity·游戏引擎