骨骼动画原理


前言

提示:这里可以添加本文要记录的大概内容:

游戏制作中,从游戏开始到现在,动画的发展经历了一个一个的阶段,效果逐渐越来越真实自然流畅。但是复杂度也越来越高。作为游戏钟不可或缺的重要模块,下面我将以unity为例聊一下,动画是怎么一步一步发展过来,以及骨骼动画的设计初衷,内部数据表示以及原理。


提示:以下是本篇文章正文内容,下面案例可供参考

一、动画的发展历程

1. 序列帧

人类最开始发明摄像机,其原理就是在很短的间隔内,按照一定的间隔拍摄连续的静态照片。在放映的时候,再将这些照片按照之前的时间顺序展现给观众看,由于时间间隔很快,观众眼睛分辨不出这些是照片,并且人会自动的想象出中间非连续的画面,那么人眼就觉得这些画面是连续的。

所有游戏动画的前身是传统动画,次技术用于早起的卡通动画,这种动画就是快速的显示一串静态图片,这些图片就叫作帧,也就是序列帧。其实现在显示器的刷新率60HZ,120HZ也是一帧一帧的快照,30帧其实人眼就已经分辨不出来是图片了。

早期的序列帧,每一帧其实是一张细小的位图,这些位图位于一张贴图上。
在这里插入图片描述
如上图所示,将每一个动画保存为一张位图,这些位图保存在一张大的贴图上,然后在渲染的时候,通过算法在不同的时间片,快速的切换这些图片的显示,已达到动画的感觉。

缺点:如上所说,每一帧的动画都要画出来,对于现在游戏来说,人物的复杂度已经越来越高,几十上百个动作很正常,而且现在对画面细腻性要求越来越高。需要一个角色的动作,以及每一帧都一个画面,每个画面也不能像之前那样用低分辨率敷衍了,可想而知的工作量,就算能画出来,内存占用也是极高的。当然这种技术还在使用,仅限于对分辨率没要求或者比较远的的物体。

2. 刚性层阶式动画

实现三维角色动画,最初的方法称为刚性层阶式动画,角色由一堆刚性部分建模而成。人形角色通常会拆分成骨盘( po torso )上臂( upper arm )、下臂( lower arm)大腿( upper leg)、小腿(lower leg) 、手部( hand )、脚部( feet )及头部( head )。这些刚性部以层阶形式彼此约束,类似哺乳动物以关节连接骨骼。这样能使角色自然地移动。例如,在移动上臂时,下臂跟手部会随之和而动。一般的层阶会以骨盘为根,躯干和大腿是其直接子嗣。
在这里插入图片描述
在这里插入图片描述
缺点:在关节位置容易产生裂缝。因此现在大多用于对刚好由刚性部件组成的机械人以及机械,刚性层阶动画就能很好的表现。
在这里插入图片描述

3. 顶点动画

由于刚性动画的不自然,于是出现了顶点动画。见名知意,就是对于角色的每个顶点,在制作动画时,每一个关键帧帧要设置所有的顶点的状态(旋转,位置,缩放),然后每一帧设置所有顶点的状态,这样可以产生最细腻的动画。

此技术有个变种:变形动画,就是在不需要每一帧都需要顶点动画的数据,而是在初始的时候只制作一些关键帧的动画,然后运行时使用插值技术,生成中间帧的状态。这样可以大大减少顶点动画的制作工程量。

缺点:虽然顶点动画表现最自然,但是想象一下,端游随便一个人形角色几十万顶点,动画师每一帧都要控制这几十万个顶点的动画!再加上需要保存这些动画信息的数据,肯定是不可能的。因此顶点动画现在主要应用于人脸的面部动画。
在这里插入图片描述
图片来源:UE4实时虚拟角色

4. 蒙皮/骨骼动画

随着游戏硬件能力的更进一步,蒙皮动画应运而生,此技术含有许多顶点动画以及变形动画的优点,又兼具刚性层阶式动画高效的性能跟内存使用量小的特性。蒙皮动画能产生接近真实皮肤跟衣着的效果。

在蒙皮动画中,骨骼(skeleton)由刚性的骨头(bone)构建而成,这与刚性层阶式动画是一样的。然而这些骨骼是不可见的虚拟概念,称为皮肤的三角形mesh网格会绑定在这些骨骼上,其顶点随着关节(joint)的移动而移动,每个顶点可以按照权重(weight)绑定到多个关节,因此关节移动时,蒙皮可以自然的拉伸。
在这里插入图片描述
图片来源:游戏里骨骼动画是怎么一回事?

如上图绿色部分展示,就圆形的为关节,关节之间的类似三角形的为骨骼。

二、骨骼的概念

骨骼( skeleton )由刚性的关节( joint )层阶结构所构成。在游戏业界,“关节”和“骨头( bone )”这两个术语通常会交替使用,但骨头一词其实名不副实。技术上来说,关节是动画师直接控制的物体,而骨头只是关节之间的空位。以 Crank the Weasel 角色模型的骨盘关节为例,它是单个关节,但由于它连接至4个其他关节(尾、脊柱、左右髋关节),骨盘关节看上去有如连接着4根骨头。图11.5详细展示了此例子。游戏引擎并不在意骨头,只在乎关节。因此每当读者在业界听到“骨头”,99%的情况实际上是指关节。
在这里插入图片描述

三、骨骼在unity中的表示

1.骨骼的层次结构

骨骼其实是虚拟概念,一般我们的骨骼层次结构,其实就是关节的层阶结构,其实就是树形结构。一般人形角色的结构如下:
在这里插入图片描述
在这里插入图片描述
这里的每个关节只是纯transform信息。

2.unity中骨骼的数据结构

在unity中,由骨骼驱动的mesh需要用到SkinnedMeshRenderer:
在这里插入图片描述
SkinnedMeshRenderer中保存了:

  • rootBone:骨骼的跟节点
  • bones:骨骼数组,每一个数据表示一个关节,在mesh中可以用索引找到对应的骨骼
  • sharedMesh:指定要渲染哪个mesh

这里SkinnedMeshRenderer其实就是指定了骨骼的transform信息。

然后看一下Mesh结构:
在这里插入图片描述
在Mesh中,保存了:

  • bindposes:绑定姿势。每个索引处的绑定姿势引用索引相同的骨骼。即跟SkinnedMeshRenderer中的bones是一一对应的。
  • vertices:保存每个顶点的位置
  • boneWeights:骨骼权重,每个顶点对应一个boneWeights

可以看到Mesh中记录的信息中,保存了姿势矩阵,以及骨骼权重信息,这样根据这些信息可以计算顶点的位置。

接下来看一下BoneWeight的结构:
在这里插入图片描述
可以看到,BoneWeight中记录了最多4个对于骨骼的索引,也就是SkinnedMeshRenderer中的bones的索引,已经受到每根bone的权重。一般:
weight0 + weight01 + weight2 + weight3 = 1

3.姿势:

无论采用哪种制作动画的技术,序列帧、刚性层阶、蒙皮/骨骼,每个动画都是随时 t 推移的。通过把角色身体摆出一连串离散、静止的姿势( pose ),并以通常30或60个姿每秒的速率显示这些姿势,就能令角色产生动感。(实际上,前面有提及,我们会为相邻的姿势插值,而非逐个姿势显示。)在骨骼动画中,骨骼的姿势直接控制网格顶点,而且摆姿势是动画师为角色带来生命气息的主要工具。因此,很明显,要为骨骼加入动画之前,先要了解如何为骨骼摆姿势。

把关节任意旋转、平移,甚至缩放,就能为骨骼摆出各种姿势。一个关节的姿势定义为关节相对某参考系( frame of reference )的位置、定向和缩放。关节的姿势通常以4×4或4×3矩阵表示,或表示为 SQT 数据结构(缩放/ scale 、四元数旋转/ quaternion 及矢量平移/ translation )。骨骼的姿势仅仅是其所有关节的姿势之集合,并通常简单地以 SQT 数组表示。

在unity中Mesh中,保存了的绑定姿势(bindposes)是一个Matrix4x4,即4X4的矩阵,表示了某个骨骼的姿势。其实每一个关节,代表了一个坐标系,其姿势受到父关节的影响,因此我们只需要跟空间变换一样,做矩阵的变换就可以知道某个关节相对于模型空间的姿势了:
在这里插入图片描述

4.姿势插值形成动画

一般动画师不会以每秒30帧或者60帧设定角色的姿势,而是利用关键帧技术,只在特定的时间设定一些重要的姿势,然后计算机会采用插值的方式计算中间的姿势。
在这里插入图片描述
实际上我们能在片段间的任何时间采样,所以这样产生的动画时间片是连续的,在计算机中t是实数,而非整数。这样就实现了真正意义上的连续。

5.蒙皮

我们把三维网格顶点联系至骨骼的过程称为蒙皮。mesh中每个顶点可以绑定至一到多个关节。若某个顶点只绑定到一个关节,也就会完全跟随该关节移动。若绑定至多个关节,该顶点的位置就等于把它逐一绑定至个别关节后的位置,再取其加权平均。
把网格蒙皮至骨骼,三维建模师必须替每个顶点提供以下的额外信息:

  • 该顶点要绑定到的(一个或多个)关节索引。
  • 对于每个绑定的关节,提供一个权重因子( bone weight),以表示该关节对最终顶点位置的影响。
  • 同计算其他加权平均时的习惯,毎个项点的权重因子之和为1。

这些信息就是unity中由Mesh保存的boneWeights所记录。下面以单个骨骼为例子,讲述蒙皮的过程。

求蒙皮矩阵的“诀窍”在于领会到,顶点绑定至关节的位置时,在该关节空间中是不变的。因此我们可以把项点于模型空间的绑定姿势位置转换至关节空间,再把关节移至当前姿势,最后把该顶点转回模型空间。此模型空间至关节空间再返回模型空间的变换过程,其效果就是把顶点从绑定姿势“变形”至当前姿势。
在这里插入图片描述
如上图所示:顶点V在模型空间先变换到对应的关节空间,然后跟着关节从绑定姿势到当前姿势,最后,在变回模型空间,这样就得到了一个顶点在动画驱动后,当帧在模型中的位置。


四、总结

其实动画的计算还涉及比较复杂的状态动画状态机,动画混合,以及GPUSkin,动画裁剪,压缩等方方面面,这里只是就骨骼动画的来源以及计算的原理帮助理解骨骼动画的驱动过程。

  • 8
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Opengl骨骼动画是一种通过在3D模型上应用骨骼结构和动画关键帧来实现动画效果的技术。在Opengl中,艺术家会将骨骼结构装配在一起,并为每种动画类型定义一组关键帧。关键帧包含了动画路径上骨骼的变换信息,图形引擎会在这些关键帧之间进行插值,从而创建平滑的运动效果。使用Opengl来实现骨骼动画需要借助辅助库如Assimp,它可以从多种格式加载骨骼信息。然而,使用Assimp加载的数据结构还需要一些工作来生成着色器所需的骨骼转换。通过使用Opengl的骨骼动画技术,可以实现人物行走、爬楼梯等复杂的动作效果。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Opengl骨骼动画](https://download.csdn.net/download/mirro187/10762824)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [opengl实现骨骼动画-(1)原理](https://blog.csdn.net/wqdqwass/article/details/121569040)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值