Skip to content

求解表面,而非骨架 ​

作者:Oleg Sidorkin,Cinevva 首席技术官兼联合创始人

第 1 部分用十二个 CC0 动物模型,将四款自动绑定工具与艺术家制作的绑定进行了比较,并发现了一个共同缺陷:它们构建的四足动物腿部几乎都是直的。文章最后提出要修复绑定,因为没有弯曲的腿无论重定向做得多好,都无法还原艺术家制作的膝部角度。

随后,我们在讨论结果时冒出了一个更简单的问题:我们究竟为什么要在骨架之间迁移动画?

骨架是一台让表面产生变形的机器。玩家真正看到的是表面,而艺术家制作的动画片段已经逐帧、逐顶点精确告诉了我们这个表面应该位于何处。因此,完全可以跳过骨架到骨架的映射。只需播放一次艺术家动画,记录变形后的网格,再求解自动绑定骨架的变换,让它自身的蒙皮尽可能还原该表面。由此得到的动画片段天然存在于新绑定自己的空间中。至于它的骨骼全都叫作 bone_0,我们也不在乎。

流程图:从艺术家动画片段到变形表面,再逐帧求解,最终得到位于绑定自身空间中的动画片段
完整流程。其中完全不需要将一根骨骼映射到另一根骨骼,因此直接消除了第 1 部分中最耗精力的对应关系问题。

这在学术文献中并不是什么新想法。它相当于蒙皮分解中的变换求解部分,也就是 Le 和 Deng 于 2012 年提出的 SSDR;动作捕捉求解器也是用这种方式将任意绑定拟合到密集标记点上的。我们的情况反而更简单:绑定工具已经提供了骨架和权重,因此唯一的未知量是每一帧的骨骼变换。

求解方法,以及确保结果可信的对照实验 ​

对于每一帧,我们为每根骨骼寻找一个变换,使绑定后的蒙皮表面与目标表面之间的距离最小。在权重固定时,每根骨骼的最佳变换都有闭式解,即使用 Horn 四元数方法进行加权刚体拟合。线性混合蒙皮会通过共享顶点将骨骼耦合在一起,因此我们依次遍历各根骨骼;每次求解都会考虑其他所有骨骼当前的贡献,直到残差不再变化。每一帧都以前一帧的结果作为初始值。

所有计算都在绑定空间中进行。无论文件以何种约定导出,蒙皮恒等关系在该空间中都严格成立。艺术家网格与绑定工具重新焊接或细分后的网格之间,则通过对齐静止姿势后进行最近邻匹配来建立对应关系。由于二者是同一个动物模型,这里的匹配是精确的。

最重要的设计原则是:必须设置一次结果为零的对照运行。我们用艺术家绑定求解它自己的动画片段;按照构造,这里必然存在一个完美答案。如果求解器连这个答案都找不到,那么它产生的其他任何结果都没有意义。对照运行的误差为模型对角线长度的 0.008%,单个最差顶点也只有 0.08%。这就是衡量其他所有结果的基准下限。

为了得到一个可信的零,我们尝试了三次 ​

第一次对照运行停在 3%,哪怕将迭代次数增加三十倍也纹丝不动。值得记录一下原因,因为从外部完全看不出这些问题。

最大的问题是一个 API 陷阱。新版 three.js 将 boneTransform 重命名为 applyBoneTransform,并悄然改变了它的行为:新函数从传入的向量读取输入位置,从不读取几何体。若传入一个重复使用的临时向量,它就会把前一个顶点的输出当作下一个顶点的输入。这样产生的目标数据看似平滑合理,实则全是垃圾。更尴尬的是,我们有整整一个小时基于这些数据提出了一套关于骨架缩放的详尽理论:它与数值吻合得极其漂亮,却纯属虚构。正确的入口是 getVertexPosition。对照实验发现了这个问题,而这正是必须设置对照实验的全部理由。

另外两个问题相对较小。Horn 矩阵上的幂迭代会停滞在大约千分之一度,因为让它收敛的谱移位也会压缩其沿途收敛所依赖的间隙。因此,我们改用了 Jacobi 旋转;对于 4x4 矩阵,它能给出精确结果。还有一个问题是,早期基于相对进度的退出测试会在遍历仍缓慢下降时将其提前冻结,因此现在的退出条件改为根据模型尺度衡量绝对进度。

每款绑定工具实际能承载多少动画 ​

验证求解器后,我们将艺术家制作的 Walk 和 Gallop 两个动画片段,分别求解到所有绑定工具均支持的六个动物模型的每套绑定中。分数表示该绑定能够还原多少运动造成的表面位移。现在我们在内部给它起了个名字:迁移质量。

各绑定工具在 Walk 和 Gallop 动画中的迁移质量点图;艺术家对照组接近 100%,RigNet 接近 50%
质量 = 1 − 求解残差 / 运动幅度,并取六个动物模型的平均值。对照行是使用艺术家绑定求解其自身动画片段的结果。
绑定WalkGallop
艺术家(对照组)99.8%99.9%
Anything World94.4%91.9%
Tripo92.3%89.1%
SkinTokens(使用艺术家骨架)82.5%89.4%
SkinTokens80.9%88.0%
RigNet48.5%58.3%

现在将它与第 1 部分比较,因为排名完全反转了。

RigNet 在四款工具中做出了最好的腿部弯曲,也是唯一一款在全部十二个动物模型上都通过可驱动性门槛的工具。但在这里,它丢失了将近一半的行走动画。其误差最大的顶点与应有表面位置的距离达到模型尺寸的 20% 到 31%;这种失败在全部六个动物模型中都十分一致,每个模型的质量都只有 38% 到 59%。与此同时,我们测得腿部最直的 Tripo 和 Anything World 反而最能承载动画。

一旦说明,二者并不矛盾。求解后的动画片段可以平移关节,而不只是旋转关节;逐关节平移轨道也是完全常规且合法的动画数据。有了平移,即使是笔直的关节链也能追踪弯曲的表面,因此腿部弯曲不再是主要限制。真正形成限制的,是蒙皮权重能否将网格划分成能够干净跟随骨骼的区域。商业绑定工具的权重做得很好。RigNet 的权重散布在不规则的骨骼链上,因此无论求解器如何移动骨骼,都无法追踪表面。

所以,这两项指标回答的是两个不同的问题。弯曲率决定了仅由旋转驱动的运行时绑定能够摆出什么姿势,这属于第 1 部分讨论的范畴。迁移质量则决定烘焙后的求解动画片段能表达多少内容,这正是本文的主题。在求解动画片段的流程下,我们已经投入使用的绑定工具拥有 92% 的质量,而不是排名垫底。

表格中还藏着另一个结果:即使把艺术家的原始骨架交给 SkinTokens,其分数也几乎没有变化。它的上限由权重决定,而不是关节位置。

亲眼观看,而不只是相信数字 ​

先看数字,再用眼睛验证。同一个求解器也驱动着一个实时查看器:每套绑定的完整网格都由求解出的变换执行蒙皮,并叠加绘制在艺术家真实表面的深色轮廓之上;每个顶点都根据其瞬时误差着色。蓝色表示零误差,红色表示误差达到模型对角线长度的 3% 或更高。

将 Walk 求解到每套绑定中。从左到右依次为:艺术家真实结果、Tripo、Anything World、SkinTokens、RigNet。RigNet 的腿部通红,每一步都会切出轮廓之外。这就是 48% 的实际效果。
Gallop 对每套绑定的考验都更加严苛。观察后腿完全伸展的时刻:Tripo 和 Anything World 仍能保持形态,RigNet 则开始散架。

画面与表格不可能彼此脱节,因为查看器使用的渲染函数与指标测量的函数完全相同。只有一个面板需要特别说明:SkinTokens 的鹿没有显示热力图。它的网格包含 181,000 个顶点,而我们会对超过 60,000 个顶点的模型跳过完整网格对应计算,因此该面板只能通过轮廓来展示结果。

这会给我们带来什么改变 ​

在浏览器 JavaScript 中,每个绑定的每个动画片段求解一次只需半秒到几秒,而且完全不使用 GPU。这个成本足够低,可以在创建绑定时直接烘焙四足动物的整套动画片段。烘焙动画片段也能简化运行时:动物完全不再需要骨架重定向,只需在绑定自身的空间中播放动画片段,再叠加我们已有的脚部锁定功能来保持与地面的接触。

它也为我们提供了第二道验收门槛。第 1 部分的几何检查判断绑定是否可驱动;迁移质量则判断它能保留真实动画的多少内容。一款绑定工具可能通过第一项,却无法通过第二项,而 RigNet 正是如此。

明确说明局限 ​

这个分数代表每套绑定的能力上限,而不是承诺。求解器可以平移关节,因此运动过程中骨骼长度并不保持不变;如果一套绑定严重依赖平移,在极端姿势下可能显得像橡胶一样。即使在表现良好的绑定上,Gallop 动画中瞬时误差达到 9% 到 20% 的最差顶点,也恰好出现在这些时刻。仅使用旋转的求解变体能够如实量化这一代价,而这正是我们仍欠缺的数据:它将揭示关闭平移后,第 1 部分中的直腿劣势还会保留多少。

投入生产的主要障碍是对应关系。在本次基准测试中,绑定工具处理的就是艺术家制作动画时使用的同一网格,因此顶点匹配非常简单。用户上传的动物会使用不同的网格,而先将艺术家的表面运动迁移到该网格本身就是另一个问题。对此已有一些已知方案,但我们尚未进行测量。

此外还有样本规模:六个动物、两个动画片段、每个片段 24 帧,并在最密集的网格上将约束下采样到五千个顶点。这足以让我们有信心对绑定工具进行排名,但不足以让我们引用到小数点后第二位。

动物模型是来自 Quaternius 的 CC0 资源;方法则是已有四十年历史的闭式拟合,再加上一些耐心。对于任何想复现这项工作的人,我们最想强调的是:请先建立对照运行。如果你以前曾将动画求解到绑定中,并遇到过我们碰到的这些陷阱,或者其他不同的问题,欢迎到我们的 Discord 交流经验。