Appearance
ARKit 与 VRM 互转方案
以 CompatibleFaceData 三层并行协议为中枢,实现苹果 ARKit 面捕数据与 VRM 模型驱动之间的双向转换,打通两个主流面捕生态。
ARKit 侧52 个 BS
VRM 侧~15 个表情
验证端PC + iOS
背景
ARKit(苹果)和 VRM(日本虚拟人标准)是虚拟人领域最主流的两个面捕协议。B 站的现状是两头都要用:iOS 原生 ARKit 引擎精度最高,但只输出 ARKit 格式的 BS;站内大量模型是 VRM 格式,只接受 VRM 表情包式的 BS。
不做互转,就是 ARKit 引擎只能驱动 ARKit 模型、VRM 引擎只能驱动 VRM 模型——引擎和模型被协议绑死,选型自由为零。
问题
- 协议互不兼容:ARKit 是 52 个语义化通道(
jawOpen、mouthSmileLeft),VRM 是少量基准表情(A、I、U、E、O),命名和粒度都对不上。 - 非一一对应:52 → ~15 是多对一映射,多个 ARKit BS 要加权合成同一个 VRM 表情。
- 美术成本翻倍:没有通用协议时,美术在蒙皮阶段要做两套 BlendShape 适配两种协议;线上已有大量基于某一种协议的模型,让用户重做一套标准的适配成本极高。
方案
不做点对点的转换器,而是把互转做进 CompatibleFaceData 通用面捕数据协议 里——三层并行结构,各层分别承载一套协议的数据:
mermaid
flowchart TD
A["面捕解算器输出"] --> B["CompatibleFaceData"]
B --> C["ARKit 层<br>52 个基础通道"]
B --> D["VRM 层<br>A / I / U / E / O 等"]
B --> E["Effect 层<br>喜怒哀乐等特殊表情"]
C --> F["ARKit 协议模型"]
D --> G["VRM 模型"]
E --> H["带特殊表情通道的模型"]驱动层不判断协议——业务方知道自己模型的驱动类型,VRM 模型就取 VRM 层的数据,ARKit 模型就取 ARKit 层的数据。协议类型不做限定:后续接新协议(比如商汤的 BS 协议)只需扩展对应层级即可兼容和互转。
关键实现
映射表
| ARKit BS 名 | 中文含义 | CompatibleFaceData | VRM BS 名 |
|---|---|---|---|
eyeBlinkLeft | 左眼眨 | EyeBlink_L | Blink_L |
eyeBlinkRight | 右眼眨 | EyeBlink_R | Blink_R |
jawOpen | 张嘴 | Mouth_A | A |
mouthFrownLeft | 左嘴角下 | Mouth_I | I |
mouthPucker | 噘嘴 | Mouth_U | U |
mouthFunnel | 嘟嘴 | Mouth_O | O |
mouthSmileLeft | 左嘴角上 | Mouth_E | E |
| ... | ... | ... | ... |
多对一加权合成
粒度粗的一侧(VRM)的一个表情,往往对应粒度细的一侧(ARKit)的多个通道,需要按权重合成后截断到 0~1:
VRM_Blink_L = clamp(
0.7 * ARKit_eyeBlinkLeft +
0.3 * ARKit_eyeSquintLeft,
0, 1
)csharp
public class ARKitToVRMConverter {
public Dictionary<string, float> Convert(Dictionary<string, float> arkitBS) {
var vrmBS = new Dictionary<string, float>();
// 多对一映射
vrmBS["Blink_L"] = Mathf.Clamp01(
arkitBS.GetOrDefault("eyeBlinkLeft", 0) * 0.7f +
arkitBS.GetOrDefault("eyeSquintLeft", 0) * 0.3f
);
vrmBS["A"] = Mathf.Clamp01(arkitBS.GetOrDefault("jawOpen", 0));
// ... 更多映射
return vrmBS;
}
}特殊表情层
Effect 层放喜怒哀乐等特殊表情,值区间 0~1,由面捕解算器从标记点计算得出。模型如果在建模时做了对应的 BlendShape 通道(模型属性面板上能看到喜怒哀乐的通道),驱动流程是:每帧拿到面捕数据 → 获取目标模型驱动类型 → 取对应层的 BlendShape 数据 → 赋到模型的 BlendShape 通道上。
指标
- PC 端 ARKit 面捕 + VRM 模型驱动验证通过;
- 移动端 ARKit(iOS 原生)+ VRM 模型验证通过;
- 线上已有模型无需重做 BS 适配,美术蒙皮从两套减为一套。
复盘
- 互转不该是转换器,该是数据结构。点对点写
ARKit→VRM、VRM→商汤的转换器会组合爆炸;把各协议做成同一数据结构的并行层,新增协议只是加一层。 - 降粒度容易升粒度难。52 → 15 是加权合成,反过来 15 → 52 只能近似——所以解算器内部永远以最细的粒度计算,输出时再按层降采样。
- 协议兼容的本质是保护存量。这个方案最大的价值不是技术多巧,而是线上已存在的大量模型不需要任何改动就能接入新引擎。