四种自动绑定器、十二只动物、一个共同缺陷:笔直的腿
作者:Oleg Sidorkin,Cinevva CTO 兼联合创始人
取一段由美术师为鹿制作的行走循环动画,将它重定向到同一只鹿经自动绑定器处理后的模型上,结果看起来会不对劲,却很难准确说出问题所在。脚掌落点大致正确,节奏也没问题,但看上去仍像一张桌子在走路。
我们曾花了不少时间,以为问题出在自己的动画重定向代码上。其实并不是。在任何动画应用到模型之前,绑定就已经错了,而且有一个指标可以清楚地说明这一点。
这个指标
取一条腿,将它从髋部到足部的各段骨骼长度相加,称之为伸展长度。然后测量绑定姿势下髋关节到足部关节的直线距离,称之为跨度。用伸展长度除以跨度。
真实动物站立不动时,腿是弯折的,因此骨骼链的总长度会明显大于它所跨越的直线距离。在 Quaternius Ultimate Animated Animals 素材包中,由美术师绑定的十二只动物,这一比值介于 1.15 到 1.50,平均为 1.30。鹿的后腿是 1.40,狐狸的前腿是 1.29。
关键在于,没有弯折的腿无法在不缩短跨度的情况下弯曲。如果关节排列在一条直线上,屈膝的唯一方式就是把脚拉向髋部。结果要么脚离开地面,要么身体下沉。让这样的绑定摆出美术师设定的膝部角度,得到的只会是一个蹲伏姿势。无论怎样调整动画重定向都无法修复,因为姿势所需的信息从未存在于骨架中。

所以问题很明确,也可以测量:绑定器是否把腿部的中间关节放在了能让腿正常弯折的位置?
测试设置
十二只动物,全部来自 Quaternius 素材包并采用 CC0 许可,每只都附带一个由美术师制作、包含 38 到 51 个关节的绑定。

网格预处理中的一个细节,实际影响远大于表面看起来的程度。这些 glTF 文件按材质把网格拆成了五个图元,而且由于模型是采用硬边的低多边形模型,几乎每个顶点都会按相邻面重复存储。狐狸模型存储了 3,752 个顶点,但其中只有 926 个不同的顶点。基于网格拓扑构建图结构的绑定器,会把这些位置重合但未共享的接缝当作裂缝,于是头部会成为与身体分离的对象,两者之间的测地距离趋于无穷,而本应位于颈部的关节也就没有理由出现在那里。在这种情况下,按位置焊接顶点并非一种优化,而是决定模型究竟是一只完整动物还是六个孤岛的关键。十二个模型中有九个在处理后形成了单一的封闭壳体。公牛和母牛的角仍是独立部件,雄鹿的鹿角也是如此;我们有意保留了这些结构,因为真实的用户上传内容通常就是这样。
评分时我们采用了两个指标。第一个是我们自己的运行时函数,它会把任意四足动物骨架归约为一种规范结构。它必须找到分处四个不同象限的四只脚,以及一条脊柱和一段颈部。如果做不到,无论绑定在其他方面表现如何,都无法在运行时驱动。
该函数完全不读取骨骼名称,这是刻意为之,而背后的原因很值得借鉴。Tripo 按索引给四肢骨骼链编号,但这些索引没有固定含义:在鹿模型中,骨骼链 0 是一对后腿,而在马模型中却是一对前腿。它对左右侧的标记在不同绑定间也不一致:面对相同方向时,鹿模型上的 Left 位于 x=-0.072,而马模型上的 Left 位于 x=+0.076。在狐狸模型上,它甚至把脊柱标记成了一条肢体骨骼链。我们尝试过的所有命名假设都经不起实测,因此改为读取绑定姿势的几何结构,因为几何结构能够无歧义地说明这一切。
第二个指标就是上文提到的弯折比。这两个指标都与缩放无关,这一点很重要,因为这些绑定器处理模型时采用的尺度差异极大。Tripo 会把模型归一化到大约一个单位立方体内,因此它的狐狸尺寸为 0.13 × 0.34 × 0.65,而美术师版本的尺寸则是 0.77 × 2.47 × 6.59。
返回的结果
| 绑定器 | 绑定数 | 可驱动数 | 平均关节数 | 平均弯折比 |
|---|---|---|---|---|
| 美术师(基准) | 12 | 11 | 46.8 | 1.299 |
| Anything World | 6 | 6 | 37.8 | 1.363(见下文) |
| RigNet | 12 | 12 | 54.1 | 1.146 |
| SkinTokens | 12 | 11 | 32.0 | 1.078 |
| Tripo | 12 | 10 | 25.8 | 1.045 |


解读 Anything World 那一行时要谨慎,因为它是这里唯一一个看似胜出、实则不然的数字。它的平均值 1.363 高于美术师绑定,但这完全是由下文将介绍的一个错误造成的。排除这个错误后,它的腿部测量值只有 1.02 到 1.18。和其他绑定器一样笔直。
因此,四种绑定器没有一个达到美术师绑定的最低弯折比 1.15。其中也包括 Tripo,也就是我们在自家 Pro 套餐中提供的绑定器。这才是核心发现,其意义远胜于一张排名表。四套独立开发的系统都收敛到了同一种错误:它们全都把四足动物的腿部关节放得近乎共线。
看明白这一点后,原因就不难理解。它们使用的数据集以双足角色和处于中性静止姿势的模型为主。笔直的肢体是最安全的平均结果,而弯曲的跗关节则是四足动物特有的结构,以人形角色为主的先验几乎没有理由学会它。
值得注意的是,基准行也并不完美。有一个由美术师绑定的柴犬模型未能通过我们自己的可驱动性测试,原因同样很有启发性。这些绑定附带一层 IK 控制结构:四个极向量目标都以根骨骼为父级,位于动物前方约半个身长的位置;另外还有四条完全没有父级的 IK 骨骼链。它们和真正的脚一样符合“足部”的几何定义,而在柴犬模型上,它们被优先识别,导致十二个候选项中有八个是误判。
这自然会引出一个怀疑,而且值得彻底排除,因为控制层干扰几何分析器听起来确实可能解释很多问题。但事实并非如此。移除控制骨并重新运行分析后,十二个美术师绑定中恰好只有一个结果发生了变化。柴犬从错误识别出的 2 条肢体恢复为正确的 4 条,其弯折比为 1.28 到 1.43,正好落在哈士奇附近。其余十一个结果完全相同,包括弯折比。因此,IK 层确实暴露了我们的足部检测错误,而且只需改一行代码即可修复,但它并不是自动绑定腿部笔直的原因。1.15 到 1.50 的美术师区间从未使用控制骨进行测量,而预测绑定中根本不存在控制层:Tripo 的骨架完全没有控制骨,Anything World 的五个非变形关节也只是末端标记。
另一方面,预测绑定采用纯 FK 也带来一个反向优势。至少在这个非常有限的方面,对于不读取命名的运行时系统而言,自动绑定动物反而比美术师绑定更容易解析。
四种绑定器的失败模式各不相同
Tripo 的腿最直,弯折比只有 1.045;它使用的关节也少得多,平均为 25.8 个,而美术师绑定为 46.8 个。但它在其他绑定器出错的地方正确还原了骨骼链的结构。它的十二个绑定中有四个精确复现了美术师的 3/3/4/4 分配方式,即每条前腿三个关节、每条后腿四个关节,而其他绑定器一次都没做到。因此,它的问题并不是关节数量不对,而是把数量正确的关节放得近乎共线。这个缺陷比乍看之下更局限,也说明重新调整现有关节的位置,可能比彻底重新绑定工作量更小。它有两个绑定完全无法驱动:狐狸只识别出两条肢体,雄鹿也是如此。

RigNet(SIGGRAPH 2020)的真实有效弯折比最高,为 1.146,也是唯一能为全部十二只动物生成可驱动绑定的系统。问题出在它的骨骼链上。美术师在十二只动物上统一采用 3/3/4/4,前后腿结构始终一致。RigNet 仅有一次精确复现了这种结构。它有三个绑定包含只有两个或更少关节的腿,根本无法产生关节运动;还有四个绑定包含七个或更多关节的腿。它的马采用 2/2/8/8:前腿各两个关节,后腿各八个关节。已发表的 RigNet 评述指出它会“输出不规则骨架”,而这就是所谓不规则在实际使用中的样子。扫描带宽参数也无法解决,因为该参数控制的是关节总数,而不是关节在各条肢体之间的分配方式。

Anything World 的失败方式不是悄无声息,而是直接报错。我们提交的八只动物中,有两只完全未能完成绑定:哈士奇返回 FinetuningError: Incorrect segmentation exception,母牛则只返回一个简单的 Unknown error。成功完成绑定的六只动物全部可以驱动。六个绑定都采用完全相同的 5/5/5/5 骨骼链,这是所有预测绑定器中最一致的结构。
问题出在它的前腿上,而且有必要准确描述其表现,因为原始平均值会让这项服务看起来好于实际情况。六个模型的后腿都精确镜像:1.10 和 1.10、1.11 和 1.11、1.13 和 1.13,以此类推,精确到小数点后五位。六个模型中有三个的前腿出现异常,其中一条腿的弯折程度远超任何合理的解剖结构,而另一条则近乎笔直。羊驼的左前腿是 3.60,右前腿是 1.87。马是 2.47 对 1.43。鹿是 1.43 对 2.13;需要注意的是,鹿的极端值出现在右侧,因此这并不是一种固定的左侧偏差。

我们重新跑了鹿和马,以排除提交参数本身的问题。symmetry 是上传时的必填字段,而存储的响应从不回显所提交的值。我们明确指定对称后再次提交,两者都重现了这一异常。因此,即便存在一个专门用来防止这种情况的参数,而且网格自身的艺术家绑定在小数点后三位都保持对称,这个问题仍然存在。
SkinTokens(2025 年,出自 Tripo 背后的 VAST-AI 团队)遥遥领先,是最规整的一个。十二个结果中有十一个的左右链长度互为镜像,而且没有任何一条腿只有两个或更少的关节。这是一套表现稳定、但站姿过直的骨架,折叠比为 1.078,而不是一套结果飘忽不定的骨架。
关于 SkinTokens,有两件事值得记下来
它会在低多边形输入上崩溃,而文档对此只字未提。我们那只包含 926 个顶点的狐狸会在请求处理中直接杀掉它的 Blender 端服务器,而且没有任何 Python 回溯。同一只狐狸细分到 88,706 个顶点后,则能在 70 秒内完成绑定。他们自己的示例模型之所以能正常工作,是因为它本来就足够稠密。在调用前增加一个细分步骤,将模型处理到大约 4 万个顶点,就让彻底失败变成了十二次绑定、十二次成功。如果输入的是游戏资产——按照定义,它们通常都是低模——那么这个前置条件就是能否工作的全部区别。
更有用的发现是,它有一种我们从未运行过的模式。传入 --use_skeleton 后,它会以你提供的骨架为条件,而不是自己生成一套骨架。随后,它会保留你给它的内容。所有输出关节都落在输入关节上,平均偏移为包围盒对角线的 0.31%,最差为 0.50%。导出时,它会把所有关节重命名为 bone_0 及后续编号,并剔除不承载任何权重的关节,这就是为什么从外部看来,这种模式似乎毫无用处。
这种重新命名是可以还原的。按位置把输出关节匹配回你提供的骨架,每个名称就都能恢复。我们在尝试的四只动物上,对 100% 的关节都成功做到了这一点。而且,因为现在骨架是你的,站姿也由你决定。让 SkinTokens 自己选择骨架时,我们的马测得 1.01 到 1.02;把艺术家的骨架交给它时,则是 1.11 到 1.36。艺术家原始骨架的结果是 1.18 到 1.37。
要让它正常工作,还有两个前提。它会直接拒绝多根骨架,而这些艺术家绑定有五个根:身体一个,外加四条 IK 链。我们最初的修复方法是删除游离骨骼,但这是错的。删除那八根骨骼后,这套动物包里的每只动物都会留下 90 到 128 个完全不受任何骨骼影响的顶点,因为艺术家正是把脚部蒙皮到 FF 和 FFB 上。它们不是无作用的辅助骨骼。将每个游离根重新设为其最近身体关节的子级,既能保留所有权重,也能得到单根骨架。
匿名骨骼名称并没有看起来那么棘手
预测得到的骨架会以 joint_0 或 bone_0 这样的名称返回,人们通常由此断定,没有任何现成动画片段能绑定到它上面。对四足动物来说,无论从哪个方向入手,这个问题都已经解决了。
如上所述,如果骨架是你提供的,就可以恢复名称。或者也可以推导名称。几何分析本来就知道哪四条链是腿、每条腿位于哪个象限,以及哪一段是脊柱、哪一段是颈部。基于这些信息重新标记,并不需要推断。我们在全部十二套 RigNet 绑定上都运行了这一流程,按运行时已经支持的命名约定写入名称,然后再次分析。十二套结果全部通过命名路径和几何路径得到完全相同的结果:相同的肢体数量、相同的象限、相同的链长度、相同的脊柱、相同的颈部,以及相同的折叠比。
第二个指标:骨架本身是否对称?
Anything World 的前腿问题促使我们测量了一个本应从一开始就检查的指标,结果它对不同自动绑定器的区分,比折叠比还要清晰。
它完全不需要读取任何骨骼名称,这一点很重要,因为一半的输出都叫 bone_0。将每个关节沿模型的对称平面反射,然后测量每个镜像点与最近真实关节之间的距离,并以包围盒对角线的百分比表示。完全镜像的骨架得分为零。对称平面取自网格包围盒,而不是关节。若允许不对称骨架自行指定对称平面,就等于允许它用自己的定义消除自身的不对称。
| 绑定器 | 平均镜像误差 |
|---|---|
| 艺术家 | 0.01% |
| RigNet | 0.08% |
| SkinTokens | 0.37% |
| Anything World | 1.08% |
| Tripo | 1.13% |

艺术家绑定在舍入精度内保持镜像,这既符合预期,也有效验证了这个测量方法。RigNet 几乎同样出色,而且这并非运气:它会显式执行对称化,在聚类候选关节之前先将其沿 x=0 反射。这个设计选择直接体现在数值上。
Tripo 排名最后,尽管差距很小;真正突出的是其结果分布,而不是平均值。它的十二套绑定中有八套低于 0.8%,但狐狸达到 15.02%,雄鹿则达到 14.45%。这两个模型也恰好是无法驱动的两个,这并非巧合:如果绑定器生成的几何结构不具备镜像关系,就无法稳定地区分身体两侧。这与前面出现的命名问题根源相同——它自己的左右标签在不同绑定结果之间互相矛盾。
这些百分比都很小。静止时,零点几个百分点的偏差肉眼不可见。但只要行走循环要求左右腿相隔半个周期执行相同动作,问题就会立刻显现。
我们准备如何处理
修复应该发生在绑定阶段,而不是重定向阶段。目前有两条可行路线,而且都比训练任何模型便宜。
一种是提供骨架,让模型只负责蒙皮。SkinTokens 已经支持这一点,并且会保留收到的骨架;对于人形角色,我们的生产级绑定器已经能够输出命名正确的 Mixamo 骨架,可以直接输入其中。另一种是重新定位现有绑定中的关节;对于 Tripo,这意味着移动腿部链上的中间关节,因为它的关节数量本来就是正确的。
我们不会做的是,把一个直腿绑定器换成另一个直腿绑定器。这样毫无收益。在真正重要的指标上,它们的范围是 1.04 到 1.15,而艺术家绑定是 1.30;它们与参考值之间的差距,比任意两个绑定器之间的差距都更大。
**更新:**后来事实证明还有第三条路线,而且它足以改变整体结论,值得单独写一篇文章。现在,我们不再在骨架之间重定向,而是从变形后的表面出发,将动画解算到每套绑定自身的空间中;由此得到的质量排名与上文完全相反。详情见第 2 部分:解算表面,而非骨架。
局限性,因为它们在这里很重要
样本量并不均衡,这限制了平均值的意义。RigNet、SkinTokens 和 Tripo 都在完整的十二个模型上运行。Anything World 运行了八个,其中六个成功生成绑定;另外两个失败时返回了明确指出问题的错误,而不是生成可供测量的糟糕绑定。Tripo 最初的五套绑定来自早期重定向工作的遗留结果,因此另外七套是在此次基准测试中,使用相同端点和相同输入完成绑定的。加入它们后,Tripo 的平均折叠比变化了 0.004,平均镜像误差则从 1.54% 降至 1.13%。这大致反映了只有五个模型的样本,会在一个方向上美化结果,又在另一个方向上惩罚结果到什么程度。
对于 Anything World,我们一开始只有两套绑定,却差点据此发表结论。两者都表现出相同的前腿异常,看起来证据确凿。随后,扩大测试后的第一个模型却返回了正常结果,于是问题突然又像是出在我们自己的提交上。直到测试了六个模型,真实规律才显现出来:一半样本受到影响,后腿始终完全正确,而出现极端值的也并不总是同一侧。只测两个模型,会让我们写出一篇信心十足却完全错误的文章——无论结论偏向哪一边。
RigNet 的检查点来自第三方镜像,而不是论文自己的下载地址,因为后者需要交互式确认并且有速率限制。因此,这些数值描述的是我们的流水线,而不是作者认证的结果。仅仅让它成功运行,就需要七项未记录在文档中的独立修复。其中一项是交互式时区提示,它会让容器构建无报错地一直卡住。另一项是调试查看器,它会打开一个窗口,然后永久阻塞。即使切换到无头模式,也无法避开后一个问题,因为它的体素化器通过 OpenGL 光栅化,所以进程必须有显示环境。
最后,折叠比假定绑定姿势是中立站姿。对于这十二只动物,它是正确的测量指标;但对于以跨步中间姿势交付的绑定,它就不适用。
这些动物是 Quaternius 发布的 CC0 资产,因此任何人都可以复现这项测试。如果你从事四足动物绑定,并且测得了不同结果,欢迎通过我们的 Discord 告诉我们。