这只老鼠还是不会眨眼
作者:Oleg Sidorkin,Cinevva CTO 兼联合创始人
我们投入了大量精力开发 Cinevva 中让模型动起来的工具:为模型绑定骨骼、添加动画,并修复模型动起来后暴露出的各种别扭细节。这些工作让我们先后处理了无法弯曲的腿、动画迁移,以及没有骨骼可供驱动的尾巴。
现在,我想让这些角色拥有一些情绪。角色不仅应该能在场景中行走,还应该能够表现出惊讶、恼怒或愉悦。这意味着要让面部动起来:眼睑、眉毛、脸颊,以及一张不再只能保持静止姿势的嘴。
我们开始研究近期的面部绑定成果,想看看能否从现有网格出发,制作出可用的表情。这是我们对这项工作的第一篇记录:哪些东西真正跑了起来、我们如何准备角色,以及实际尝试后的结果。
测试对象是之前处理尾巴时用过的那只老鼠。它已经拥有身体骨骼和六个动画片段,能够行走、跳跃和冲刺,但在所有动画中,它的脸始终一动不动。
我们尝试了 NFR。这是一个研究实现,可以把表情迁移到给定的面部网格上。第一份输出是一组姿势图,标注着张嘴、微笑、眨眼、噘嘴和挑眉。我看不出其中有什么真正可用的动画。张嘴动作把口鼻部扯变了形,而其他大多数图片看起来几乎一模一样。
在判断结果之前,还有一个值得修正的准备问题。制作输入网格时,我们切掉了老鼠眼眶边缘的大部分几何体。因此,我们重新裁剪并再次运行,然后把两次尝试都渲染成动画。结果如下。
NFR 的输入内容
完整角色导出后有 22,744 个顶点和 30 个关节,但没有面部混合变形,也没有专门用于下颌和眼睛的骨骼。我们需要在不影响现有骨骼绑定的前提下添加面部控制。
NFR 的输入要求解释了为什么我们不能直接把 GLB 交给它。它需要一个眼睛和嘴部已经切出开口的面部表面,不能包含内部结构和眼球,而且网格应与其示例大致对齐。我们移除了后脑、耳朵和颈部,制作了开口,并保留最大的连通部分。最终剩下 777 个顶点和 1,296 个三角形。
裁剪网格中的每个顶点依然对应原始角色上的一个位置。推理完成后,我们从每个预测表情中减去预测的中性面部,将偏移转换回老鼠所使用的缩放比例,再将其应用到原始网格中相匹配的顶点上。越靠近裁剪区域边缘,位移越弱,以免面部与头部其余部分的交界处突然停止变形。
这样,我们得到了九个混合变形:它们以顶点偏移的形式存储,可通过滑块混合到中性网格中。将所有滑块设为零,就会恢复原始老鼠。我们保留了它的骨骼、纹理和六个身体动画片段,然后为每个表情单独添加了一个测试动画片段。
加载检查点和输入后,推理本身在 T4 上大约需要七秒。但要得到可用的表情,显然还需要更长时间。
我们切掉了真正需要的部分
第一次切眼部开口时,我们使用了较宽的椭圆形。对于这张脸来说,这会移除每只眼睛周围大部分的眼眶边缘。嘴部切口则位于可见唇缝下方。仅从描述网格的数据来看,这两个错误都不明显:坐标均为有限值,没有退化三角形,也没有非流形边。
但观察裁剪后的网格,问题就相当明显了。我们先丢弃了大部分本可用于眼睑运动的表面,却又要求它产生眼睑动画。
第二次处理时,我们分别从正面和两个斜侧角度渲染了头部。我借助助手的图像理解能力,标记了眼部开口、眼眶边缘、唇缝、口鼻部、鼻子、眉毛和胡须。这些轮廓随后被投影到原始网格中可见的三角形上。保留投影信息和三角形 ID 后,我们便能检查每次裁剪究竟保留了面部的哪些实际部分。

我们将 131 个可见三角形标记为两侧眼眶边缘的一部分。第一次裁剪只保留了其中 25 个,而新裁剪保留了 123 个。这确实改善了输入,不过该数据衡量的是相对于我们自己标注的保留率,而不是独立的分割准确率。
我们还调整了对齐方式。我们没有继续匹配之前的参考范围,而是使用对应的面部特征点来确定统一缩放比例和位置。新裁剪包含 586 个顶点和 952 个三角形。它仍然存在缺口和开放边界;这次处理只是选择现有几何体,并没有创建新的眼睑或口腔内部结构。
动得更多,也拉伸得更严重
第二次运行使用了相同的权重和相同的九个表情控制。这一次,我想查看完整的运动过程,因此我们渲染了从中性状态到每个完整表情之间的中间强度,然后再回到中性状态。页面顶部的视频展示了两个版本在相同灯光下的效果。
眼睛依然保持睁开。下颌控制改变了口鼻部,却没有形成可信的张嘴效果。部分嘴部控制比以前产生了更多运动,尤其是收拢嘴形,但表面也随之发生了扭曲。
我们检查了边长,以量化这种扭曲。对于角色网格中的每条边,我们用完整表情状态下的长度除以中性状态下的长度,并统计长度增加到两倍以上的边。
| 控制项 | 第一次裁剪:超过 2× 的边 | 修订后裁剪:超过 2× 的边 | 修订后的最大拉伸 |
|---|---|---|---|
| 张嘴 | 13 | 44 | 5.27× |
| 左侧微笑 | 0 | 30 | 5.53× |
| 收拢嘴形 | 0 | 89 | 11.29× |
短边很容易产生较大的比值,因此我不会单独使用这项数据来评价面部绑定。但在本例中,它与渲染结果一致。修订后的嘴部动作幅度更大,其中一部分却是我们不希望出现的拉伸。
我们同时更改了三项内容:裁剪、对齐,以及外边界处的衰减。仅凭这次对比,无法判断每个瑕疵分别由哪项更改引起。但可以确定的是,整体而言,修订后的准备方式并没有解决这个角色的面部问题。
为什么选择 NFR
在进行这次实验之前,我们也研究了其他实现。Google 的 GNM Head 可以加载,并在自带的人类头部网格上生成表情。但要把这些表情应用到我们的老鼠身上,还需要额外的拟合与迁移步骤。Example-Based Facial Rigging 则需要相互对应的表情示例,而我们的角色并不具备这些数据。
RigAnyFace 和 OmniFaceRig 也与这项工作相关,但截至 2026 年 9 月 11 日,我们尚未找到可供运行的公开推理代码和权重。OmniFaceRig 的数据集链接仍显示“即将推出”。NFR 提供了已发布的检查点和处理自定义网格的流程,因此我们最终选择它,并一路做出了带动画的老鼠。
这并不是五次可直接比较的运行。我们在自己的面部表面上测试了 NFR,在 GNM 自带的头部网格上检查了它的效果,而其他方案则因输入要求或可用性限制而止步。
下一次尝试需要真正的眼睑
之前的裁剪确实很差,修正它也很有必要。但保留眼眶边缘,并不意味着它拥有足够的几何体或正确的运动方式来覆盖眼球。嘴部也存在类似问题:我们可以拉动口鼻部,但这次实验并没有构建该姿势所需的开口和内部结构。
接下来,我会先集中处理一次眨眼和一次张嘴。让眼睑具备能够闭合并覆盖眼球的形状,准备好嘴唇和口腔内部,再为这两个动作拟合或手工制作修正形态。在添加其余控制之前,还需要同时从侧面和正面检查效果。
我们保留了两次尝试的全部内容,包括原始预测结果和精确的裁剪数据,以便今后将新成果与这次结果进行对比。目前,身体骨骼及其动画仍然完好无损。面部形态依然只是实验结果;我不会把它们用于成品角色。