怎么绑定一个手?也并不是那么简单,这里笔者简单记录下自己在Maya中的实验的步骤和注意,以及整理了一些参考资料。


1. 模型拓扑

作为游戏内模型,首先要考虑的是面数。如何在低面数的条件下,保证变形效果?这就需要巧妙的布线。一般原则是:

  • 对会扭转和弯曲的关节处给环状布线
  • 给可能需要变形的突起和皱褶处多一些圈数。

这样的主要考虑是,避免变形后,模型的轮廓出现明显的转折。
比如上图给了一个不错的布线走势示意图。美中不足是手背上这样布线有点浮夸。笔者按照上图参考,建了一个低模。
绑定一只手_java图片来源:笔者自绘


2 直接绑定

手就是五个手指,骨骼没什么复杂的。
绑定一只手_java_02
骨骼的建立可以使用DCC自带的套件,比如Maya的HIK,Max的Biped等。
绑定一只手_java_03HIK的手 图片来源:笔者自绘
也可以自建骨骼,只要注意轴向和旋转顺序就好
绑定一只手_java_04笔者自建骨骼 图片来源:笔者自绘
然后,加上蒙皮权重,就可以动了!不过这有个问题,权重怎么来的?如何做一个好的蒙皮权重?一般需要艺术家较多的经验来保证。不过,也有自动建骨骼,自动生成蒙皮权重的方法。比如Maya的Geodesic,Houdini的Biharmonic等等。可参见 2014 Siggraph Skinning Course 第二讲Automatic Methods。但是,这些自动的方法最终仍需要艺术家的手动修正。这也还没结束。这样虽然可以动了,但是有一些问题:

  1. 线性混合蒙皮本身旋转插值的缺陷,导致扭曲变小等效果

  2. 一些肌肉和关节会在变形后凸出,无法用权重补偿修复


对第一个问题的解决方案可以是优化蒙皮算法。比如Dual Quaternion,比如Direct Delta Mush等等,这里便不再赘述。2014 Siggraph的Skinning Course是一个很好的教程,第一讲Direct Method就是讲的这些。对于第二个问题,就需要其他方法来解决.


3. 基于范例,手工方法

前文提到的,对于肌肉和关节变形的模拟,我们可以用基于”范例“的方法来解决。即,给定某个姿态下的模型变形效果(就是范例);让变形在目标姿势时,趋近预先给定的范例的变形效果。
绑定一只手_java_05图片来源 http://www.skinning-org.alecjacobson.com/example-based.pdf
范例的制作,可以用比较手工的方式。让艺术家手工做出在某个姿势下模型的变形效果,作为Corrective Blendshape的方式,在这个姿势下使用这个变形。这也就是Pose Space Deformation(PSD)的思想。
绑定一只手_java_06PSD的一个范例,上:PSD,下:经典LBS。图片来源: http://www.skinning-org.alecjacobson.com/example-based.pdf
当然,我们不是非得给模型顶点”范例“。否则的话面数内存可能会比较高。我们也可以把PSD的思想在骨骼系统上实现。比如我们可以有一些用来修形的骨骼,称为“次级骨骼”的变形,让它在特定姿势下变形。这样配上顶点权重的设定,就可以模拟模型在特定姿势下的变形。变形的效果,比如在这里, 会让掌指关节和掌丘凸起。
绑定一只手_java_07让掌指关节和掌丘凸起 图片来源:笔者自绘。
对不同姿势的插值就是用PSD中提到的RBF。笔者在之前文中有提到。模型变形从FFD到RBF只不过,这里为了实时性的考虑,并不需要做一步线性方程求解来归一化RBF的权重,而是直接在UI上控制高斯函数的标准差宽度就好了。大概读了一下UE4的RBFSolver也是这样的trick。这里,笔者自己写了一个工具,可以给一些次级骨骼添加约束,让它在主骨骼不同姿势下,变形到需要的位置。
绑定一只手_java_08编辑姿态的工具,图片来源:笔者自绘
实际实现上,写了一个节点来解算这个RBF的插值结果在此基础上,我们还可以加入Wrinkle Map的方法,用关节变形角度来驱动法线贴图的混合,表现皱褶绑定一只手_java_09指关节的Wrinklemap,图片来源:笔者自绘
用来控制Wrinkle Mask范围一般画几个mask写个shader就行比较简单。绑定一只手_java_10一张Wrinkle Mask 图片来源:笔者自绘
除此外,为了方面Animator工作,还需要设定绑定系统控制器,建立IK和FK的控制器。
绑定一只手_java_11FK与IK的控制器,图片来源:笔者自绘
到此为止,也就是本世代(PS4)游戏中的常用绑定做法。不过,这有个问题。艺术家/ 绑定师凭经验建立的变形范例是否”正确“。当然,游戏不一定追求正确,一个好的美术方向更重要。但这是后话了。为了追求变形的”正确“,我们就得使用数据驱动的方法。


4 基于范例,数据驱动

最好是直接就有3D扫描的模型数据了,这样我们可以直接用扫描的模型作为“范例”。一般来说,我们将”范例”姿势作为基姿势,作为可以有两种方案:

  1. “人工定义”,预先定义好“基”姿势,也就扫描这些基姿势。就像FACS的做

  2. “机器学习”,求解每个pose对应的“范例”权重。或者直接求出”基姿势”



第一种方案的问题是,怎么人工定义基姿势,是否有可解释的意义,并使它们正交。比如FACS是一个成熟理论,但是手如何定义?第二种方案的问题是,可解释性比较差,比较难以让人直观理解,很难用它手K动画了。这对于动画也有个问题,无论是使用“范例”权重的方法,还是基姿势的方法,我们都把模型变形分解为了一个参数向量。但这可能会对动画师带来问题,操控起来并不直观。好在,当如果有扫描模型的话,大概率也会有动作捕捉的动画方案,这样只要把动作捕捉的动画,分解到模型变形的参数空间就好了。比如笔者实验第一种方案。首先是模型制作上,可以用Wrap3将游戏低模套到扫描高模上面。使用ultimate female hand pack,原始模型是11个3D扫描的手,笔者套用了11个pose的低模。
绑定一只手_java_12wrap3 套用了11个pose的低模 ,图片来源:笔者自绘
其次, 对游戏中使用来说,Blendshape也不是不行,但是最好是能用骨骼变形代替Blendshape。对于骨骼的求解,Skin Decomposition是一个很好的方法。它可以求解出,满足输入blendshape的变形误差最小的骨骼权重与动画。比如,EA开源的Dem-Bones就是一个生成SSDR的很好的工具 。笔者曾经介绍过这个技术 蒙皮分解Dem-Bone的一个好处是,可以锁定部份骨骼,只求解其余的骨骼。这样我们可以手动k出对应每个扫描模型的主骨骼的pose,交给dembones生成“次级骨骼”的变形。这样就可以求解出每一个“范例”模型中,次级骨骼的变形。虽然不同关节之间会有相关性。但如何定义基姿势呢?如果以骨骼自由度定义基姿态的话,那需要三十多个呀。因此笔者这个常识不是很成功,做不下去了,输入模型不够,并构造不出来基姿势。只有11个Pose,但是有30个左右DoF绑定一只手_java_13希望得到的结果是,每一个滑杆可以控制一个基姿势,不过数据太少并不成功。图片来源:笔者自绘
对于第二个方案,可以有简单粗暴的方式,比如模型顶点变形不需要权重,全部用神经网络生成。但也有其他巧妙地方案。

一个经典的案例是Weighted Pose Space Deformation, 在 Modeling deformable human hands from medical images 这篇文论中,它求解每个pose对应的“范例”的权重,来做不同姿势下不同范例的混合。这样它只扫了几十个模型就够了。另一个巧妙的方案来自于马普所MPI,也就是SMPL模型的同一组:Embodied Hands: Modeling and Capturing Hands and Bodies Together在模型变形方面,它也是一个PSD的思想,依然用LBS做权重变形计算,对于不同pose用blendshape做纠正。不同的是,姿势用PCA做分解,而Blendshape也是学习出来的。首先扫描了三十多个手,每个都很多pose,最终扫描了两千多个模型。
绑定一只手_java_14图片来源:Embodied Hands: Modeling and Capturing Hands and Bodies Together
最终成果是一个数据模型,输入一个形状向量和一个姿势向量生成手的模型
绑定一只手_java_15图片来源:Embodied Hands: Modeling and Capturing Hands and Bodies Together
论文中从数据学习出了Pose Space Deformation得出的corrective blendshape。下图中,绿色的是带blendshape纠正的模型输出,粉色的是数据集,黄色的是corrective blendshape。
绑定一只手_java_16图片来源:Embodied Hands: Modeling and Capturing Hands and Bodies Together
至于姿态空间,一个PCA出来发现,6个自由度(基姿态)就能表示80%的姿态了下图是学习出来的前十个基姿态。
绑定一只手_java_17图片来源:Embodied Hands: Modeling and Capturing Hands and Bodies Together
不得不感慨,有数据就是可以为所欲为。


5 讨论

其实,还有基于肌肉的技术,比如Ziva Dynamics这种,笔者还不是很了解也就略过了。以上,整理了绑定一个模型,个人了解的用到的技术,以及一些成功或不成功的实验。直到今天二十年过去了,Pose Space Deformation的思想仍然很重要。毕竟这方面不是很专业,如有错误,请读者指正。业内实践上,在本世代(PS4)中,对于脸部的绑定,已经使用了数据驱动的基于范例的方法,比如战神4中讲到的脸部绑定。而身体其它部分,主要还是手工制作的基于范例的方法。而对于贴图细节的表现,仍然是wrinklemap的做法。对于卡通角色,可能主要还是手工制作的基于范例的方法吧。而简单的场景下,直接绑定仍然是一个可行的选择。下时代的写实游戏,有可能更多会用到数据驱动的方法,比如SMPL这类基于数据的身体参数模型。而对于风格化的游戏,使用数据驱动的方法也并非不可行,无非只是用人类Artist来制作范例嘛。主要得益于机器学习工具的普及,大家都来pytorch。