Skip to content

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 模型——引擎和模型被协议绑死,选型自由为零。

问题 ​

  1. 协议互不兼容:ARKit 是 52 个语义化通道(jawOpen、mouthSmileLeft),VRM 是少量基准表情(A、I、U、E、O),命名和粒度都对不上。
  2. 非一一对应:52 → ~15 是多对一映射,多个 ARKit BS 要加权合成同一个 VRM 表情。
  3. 美术成本翻倍:没有通用协议时,美术在蒙皮阶段要做两套 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 名中文含义CompatibleFaceDataVRM BS 名
eyeBlinkLeft左眼眨EyeBlink_LBlink_L
eyeBlinkRight右眼眨EyeBlink_RBlink_R
jawOpen张嘴Mouth_AA
mouthFrownLeft左嘴角下Mouth_II
mouthPucker噘嘴Mouth_UU
mouthFunnel嘟嘴Mouth_OO
mouthSmileLeft左嘴角上Mouth_EE
............

多对一加权合成 ​

粒度粗的一侧(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 只能近似——所以解算器内部永远以最细的粒度计算,输出时再按层降采样。
  • 协议兼容的本质是保护存量。这个方案最大的价值不是技术多巧,而是线上已存在的大量模型不需要任何改动就能接入新引擎。

罗子初 · AI 座舱专家 · 8年端侧研发

Lv.1