UWA

每天一点UWA:动画重定向笔记

Posted by 蔡华的博客 on November 8, 2017

基本原理

  • 动画重定向技术主要是针对骨骼动画的方案,由骨骼来描述动作信息,用蒙皮来表示模型网格与骨骼之间的关系,从而得到模型最终的样子。 image
  • PS:这张图很形象

  • 动画就是每一帧为模型制作一个Pose(姿势),在每帧之间的姿势可以通过差值获得。

最简单的情况:只有骨骼大小不一致的情况

  • 此时因为骨骼在模型空间中具有一个对应的位置,因此以大人和小孩的骨骼为例,是没办法直接将大人的动画信息用在小孩的骨骼上的。
  • 如何解决这个问题的呢?unity使用了一个参考姿势(通常情况下,会把T-Pose作为参考姿势)来计算不同大小骨骼之间的差值,然后应用到动画数据上。

a1是A骨架的参考姿势,b1是B骨架的参考姿势,动画中某一帧的姿势是a2,我们想得到的结果是b2,我们认为,a2与参考姿势a1的差异应当和b2与其对应的参考姿势b1的差异相同,即:

a2 - a1 = b2 - b1

我们可以得到计算过程为: b2 = a2 - a1 + b2 = a2 + (b1 - a1)

参考姿势a1和b1都是提前得到的,因此可以进行预先计算好b1-a1的值。要知道这里的加法和减法要转换为每根骨骼的PRS计算,因此还是有不少CPU消耗的。下图给出了使用一个简单整数代替骨骼的PRS数据来模拟动画重定向的计算过程。 image

  • 不同引擎的实现上可能不一样,文中提到了Havok的实现。
  • 以上就解决了骨骼长度不一致的问题。

真实的世界:骨骼名称、数量、父子关系不一致的情况

  • 首先在如果项目中确定使用动画重定向,那么在模型制作时就需要约定好名称、数量和关系。

骨骼名称不一致

  • 对于CS骨骼,由于在3DS Max中通常美术只会添加不同的前缀,因此可以通过去除前缀的方式进行模糊匹配来做骨骼映射;
  • Unity的做法细节不清楚,但是感觉会根据整个骨架的父子关系和结构来进行映射关系的计算;
  • 而对于Bone骨骼,在没有预先定义好类似最大化骨骼这样规范的情况下,非常难通过程序来判断映射关系,可以提供可视化编辑的功能来让美术自己定义它们之间的映射关系。

骨骼数量不一致

在非CS骨骼或者不重要的部分存在多余的骨骼
  • 如果动画文件的骨架中存在多余骨骼,通常的做法是把这些骨骼忽略掉,而如果目标骨架上存在多余的骨骼,即有些骨骼原始动画中并不存在,这其实没有办法为它生成动画,只需要保证其保留在原始姿势的local space当中,即让其跟着父骨骼移动。比如身上的飘带,如果原始动画中没有,在不使用布料系统等物理方案的情况下,只能让其按照参考姿势中的样子,“僵硬”地跟随角色移动。
在重要的位置存在骨骼不一致
  • 多图,请直接看原文。解决的办法就是使用链式映射。
  • 链式映射要做的就是将多根骨骼组成的骨链A和另外一个骨骼中多根骨骼组成的骨链B进行映射,做到整条B骨链的样子和A骨链的样子相近。

骨骼父子关系不一致

  • 当两套骨骼的父子关系都不一致的情况下,其实很难得到正确的映射,简单的不一致可能可以容忍,但是可以想象,把一个人形骨骼的动画映射给四足动物甚至蜘蛛这样的八脚动物,是一件非常难做的事情。
  • 也因为这样的原因,目前大范围应用的动画重定向,基本还是在人形骨骼上,当然,用相同的算法,把四足的战马动画映射到不同的体型的战马上也是可以的。基本的原则是骨架尽量具有更多的相似性,重定向的效果也就会更好。

Unity中的重定向

  • Unity引擎中动画重定向的实现不是一个直观的方法,而是封装在了Humanoid类型的动画系统里面,==也就是必须是人形的骨架、==使用Humanoid才可以使用它====
  • Unity没有像前文描述的基本原理那样去定义两套骨架之间的映射关系,而是自己在内部定义一套骨架模板,所有的Avatar骨骼都必须映射到这套模板上才可以由同一个Animator来驱动产生Retargeting之后的动画效果。
  • 关于如何预览一个重定向之后的动画的效果,只能把模型放到Scene中,设置同一个Animator来观察。在动画文件的预览窗口,如果拖拽另外一个模型文件到其中,并不能预览到正确的效果。 PS:话说我以前都是这么干的。。
  • PS:具体操作过程参考原文或者unity文档吧,就是avatar设置那套流程。不过unity的avatar里面还能改变肌肉控制。

使用中的一些问题

角色的武器或者飘带在使用Humanoid类型的动画系统之后不会移动了,或者移动的位置有了很大的偏差。
  • 这时候可以在动画文件的属性设置里,查看Mask下的Transform选项,里面可能存在没有被勾选的骨骼。目前的做法是把Transform下的所有骨骼对象都勾选上。
角色的武器在动作中出现了乱飘的情况,与手部无法紧密地绑定在一起
  • 由于我们最初为了方便美术制作武器的动作,把其父骨骼设置给了盆骨这样一根相对稳定的骨骼,但是经过Retargeting计算之后,由于角色身材不同产生了一些偏差导致。最终我们还是把武器骨骼的父骨骼设置为手部的骨骼,才解决了这一问题。
某些角色在重定向之后的动画中表现为脚不贴地,和地面之间有缝隙,原始动画中没有
  • 可能是重定向算法或者是参考姿势这两个因素导致
  • 在avatar设置中,可以看看目标骨骼在T-POSS是否正常。

性能消耗

  • 通过前面的原理分析可以看出,即使在有预计算的情况下,与普通的动画计算,Retargeting的过程还是有一定的CPU消耗的,但是这与通常会造成CPU瓶颈的蒙皮、渲染指令提交等相比,其实消耗并不算大。
  • Unity与Retargeting相关的还制作了肌肉控制的功能,Humanoid形式的动画系统相对于Generic形式的动画系统虽然有一部分额外的性能消耗,但是Unity内部做了比较好的优化,差别不是很大,因此可以放心使用。

补充

一些概念

  • CAT和CS之前都是插件形式出现的
  • CS主要是用来创建两足动物的比如人类
  • CAT不但可以创建两足动物还能创建多足动物,这就是CAT相对于CS最大的优势了。
  • bones是3DMAX原始的骨骼系统,这个骨骼你需要自己手动创建才行,而CAT和CS可以自动生成
  • skin是蒙皮系统,就是用骨骼对模型进行蒙皮后模型和骨骼产生关联,这样模型就能跟着骨骼一起运动了。

原文

  • https://blog.uwa4d.com/archives/AnimationRetargeting.html