动画重定向技术分析和Unity中的应用

1. 什么是动画重定向

动画重定向,即Animation Retargeting,是一种动画复用的技术,直观上,你可以把它的作用想象成周星驰电影《西游-降魔篇》里的“听话符”——“我做什么,你就跟我做什么”。

这里给出一个非官方的定义:

Retargeting is just the process of “copying” the animation from one skeleton to the other.

简单来说,重定向技术就是一种在将动画数据从一个骨架拷贝到另外一个骨架的过程,只是这个所谓的“拷贝”过程,没有Ctrl+C、Ctrl+V这么简单,其实现的方式,也会影响到动画应用到另外一个骨架之后的效果。

2. 为什要使用动画重定向

动画重定向技术在很多地方已经得到很广泛的应用,比如目前3A级主机游戏常用的动作捕捉技术就是基于这个原理来实现的——将真实人物 的动作通过图像识别等技术生成动画信息应用到虚拟的角色身上,保存成动画数据。还有Max和Maya这样的建模工具中,也都已经集成了这一技术,用来方便美术把一个动作文件复用到其他骨架上。

那什么样的游戏开发需要这样的技术呢?我们可以假想如果要开发类似《街霸》这样的3D格斗游戏,其中有几十个不同体型姿态各异的角色,战斗过程中会有很多抓技和投技的动作表现,对于这一类型的技能,不同角色的受击动作应该是一致的。

如果使用最常规的制作方法,需要对每一个角色制作攻击动作对应的受击动画,或者需要限制策划设计的受击表现在使用固定姿势、挂接、特效等方式可以实现的范围内。而不甘平庸的策划同学往往需要更加复杂的受击表现,常规的制作方法带来的问题有如下三个方面:

a) 美术工作量较大。 如果有n个不同角色的骨架,有m个需要特殊表现的技能,那么只考虑受击动画就需要m*n个,这个数量级通常会在几千个动作的级别。美术需要制作、导出这些动画文件,需要非常大的工作量。

b) 动画维护困难。 想象下,策划设计了一个需要特殊动作表现的技能,美术加班加点制作出了所有英雄的受击动画,第二天黑着眼圈来上班,策划同学满脸讪笑地走过来说——“哎呀,你看,这个受击动作的第15帧有点不自然,力量感不够强,要你不优化一下?”……每一处修改都需要美术手动同步到其他动作文件上,重新调整导出,这一过程太过费时费力。

c) 游戏发布打包文件过大。 动画文件多必然带来这一问题,尤其是在手游中,包体大小通常是安卓渠道发行的一个需要考虑的重要指标。

而动画重定向技术就是一种时间换空间的思路,在运行时将一套动画根据预计算好的骨骼差异信息,得到目标模型骨架上可以适用的动画数据,就可以生成目标角色的受击动画效果。这种方式既可以减少美术的工作量,又可以增加游戏对策划需求和修改的灵活度,将需要维护和打包的动画数量从m*n这样的平方级别降低到m个。当然,软件工程中“没有银弹”的定律在这里依旧生效,重定向之后的动画可能由于体型差异等问题在某些情况下无法完全满足策划或者美术的要求,这就需要一些额外的方法或者重新制作部分动画来进行弥补,这部分放在后面进行详述。

3. 基本原理

写到这里,其实之前有一点没有说明的是动画重定向技术主要是针对骨骼动画的方案,由骨骼来描述动作信息,用蒙皮来表示模型网格与骨骼之间的关系从而得到模型最终的样子。对于这块不熟悉的读者可以自己查阅一下相关的资料。

动画重定向的过程主要是针对骨骼信息,对于蒙皮过程没有任何影响。而动画信息,可以理解为每一帧中所有骨骼数据信息的集合,更加形象地理解,动画就是每一帧为模型制作一个Pose(姿势),在每帧之间的姿势可以通过差值获得。

为了更加清楚地描述动画重定向地原理,我们截取某一帧的姿势来进行分析——在解决了每一帧的姿势重定向之后,整个动画的重定向也就是在每一帧都进行姿势的重定向即可。

假设有两个模型,他们的骨架分别是A和B,我们拥有A骨架对应的动画数据,想把这个动画数据应用在B骨架上。直接应用是否可以?当A骨架和B骨架完全一样的时候,直接应用是可以的,但通常动画重定向要处理的是骨架不太一样的情况。这些不一样的情况有很多种,比如:
a) 骨骼数量不一致;
b) 骨骼父子关系不一致;
c) 骨骼名称不一致;
d) 骨骼本身的长度等数据不一致。

对于前几种不一致情况的处理,我们在基本原理的部分先不进行分析,对于骨骼数量一致、骨骼父子关系也相同这样最为简单的情况下,我们来看一下动画重定向的基本方式。

先明确在这种情况下,直接应用A的动画数据到B上会存在的问题。想象一下,A是一个身高为1.8m左右的大人骨架,而B是一个身高为1.5m左右小孩骨架,A的动画信息记录的骨骼位置(Position)、旋转(Rotation)和缩放(Scale)信息都是针对于大人的,比如经过最终的计算,在Idle动画中的某一帧姿势中,模型空间下A的Head这根骨骼可能在距离地面1.7m这样的位置,而同样的动作让一个小孩B来做,也把Head骨骼放置在1.7m的位置,蒙皮之后的结果会非常奇怪,出现拉伸等问题,因为B的身高整个才是1.5m。

为了解决这个问题,或者说一个正确的动画重定向过程,是基于所谓的参考姿势(Reference Pose)的。通常情况下,会把T-Pose作为参考姿势。引入参考姿势之后,动画数据不再直接应用到目标骨架上,而是把动画姿势与参考姿势的差异应用到目标骨架上。a1是A骨架的参考姿势,b1是B骨架的参考姿势,动画中某一帧的姿势是a2,我们想得到的结果是b2,我们认为,a2与参考姿势a1的差异应当和b2与其对应的参考姿势b1的差异相同,即:

a2 - a1 = b2 - b1

我们可以得到计算过程为:

b2 = a2 - a1 + b1 = a2 + (b1 - a1)

这其中,a1和b1的数据是在游戏发布时就确定的,因此可以进行预先计算好b1-a1的值。要知道这里的加法和减法要转换为每根骨骼的PRS计算,因此还是有不少CPU消耗的。下图给出了使用一个简单整数代替骨骼的PRS数据来模拟动画重定向的计算过程。

更多unity2018的功能介绍请到paws3d爪爪学院查找。链接https://www.paws3d.com/learn/,也可以加入unity学习讨论群935714213

近期更有资深开发人士直播分享unity开发经验,详情请进入官网或加入QQ群了解

猜你喜欢

转载自blog.csdn.net/qq_35037137/article/details/88764914