DeskMate

形象配置格式

告诉 DeskMate 如何驱动 VRM 或 Live2D 模型的 avatar.json,附一份从零开始写配置的教程。

核心从不指名某个 Live2D 动作或 VRM 表情。它只说一套小而与渲染器无关的词汇(ADR-0004):

  • 情感(affect):一个点 (valence, arousal),各在 [-1, 1],外加当前正在表达的感受(joy、sad 等);
  • 手势:nod、shake、tilt_head、wave;
  • 待机状态:idle、listening、thinking、speaking、sleeping;
  • 视线:指针、用户,或屏幕;
  • 嘴型:一个张开程度,由声音的响度驱动。

每个模型都配一份映射 avatar/avatar.json,把这套词汇翻译成这个模型自己的部件。有两种形状,由 kind 决定。

它放在哪里:每个角色有一个目录,里面的 avatar/ 文件夹放模型和 avatar.json(~/Library/Application Support/DeskMate/characters/<id>/avatar/)。你很少需要从零写它:在控制台的角色页导入模型会生成一份(见导入会生成什么),不过你可以手工改。

通用字段

字段含义
kind"vrm" 或 "live2d"。必填。
model模型文件的路径,相对于 avatar/。必填。.vrm 或 .model3.json。
scale在自动适配窗口的缩放上再乘的倍数。默认 1。
expressions表情锚点(见下)。

表情:情感空间里的锚点

锚点是放在 (valence, arousal) 空间里某个点上的一张有名字的脸。渲染器选离角色当前情感最近的锚点,并一直用它,直到另一个明显更近,这样脸不会闪烁。切换时有约 300 毫秒的淡入淡出。

{ "name": "joy", "valence": 0.7, "arousal": 0.3, "…": "…" }
  • 要给一个中性锚点("valence": 0, "arousal": 0)。
  • 角色说出一种感受时(台词里的 [affect joy]),名字和这个词相同的锚点,优先于最近的那个。这些词是 neutral joy excited calm sad angry scared surprised shy bored。用它们给锚点命名,就能得到这个行为。它们的默认位置:
词valencearousal
neutral00
joy0.70.3
excited0.70.8
calm0.4−0.5
sad−0.6−0.4
angry−0.40.8
scared−0.80.4
surprised0.10.9
shy0.30.4
bored−0.3−0.7

VRM

{
  "kind": "vrm",
  "model": "mio.vrm",
  "expressions": [
    { "name": "neutral", "valence": 0, "arousal": 0 },
    { "name": "joy", "valence": 0.7, "arousal": 0.3, "weights": { "happy": 1 } },
    { "name": "excited", "valence": 0.7, "arousal": 0.8,
      "weights": { "happy": 0.8, "surprised": 0.5 } }
  ],
  "gestures": {
    "wave": { "vrma": "wave.vrma" }
  }
}

表情。 weights 混合模型自己的表情,每项在 0 到 1 之间。名字可以是 VRM 1.0 的预设名(happy、angry、sad、relaxed、surprised),也可以是模型自带的自定义表情;VRM 0.x 的预设在加载时会改名(joy→happy、sorrow→sad、fun→relaxed、a→aa 等),所以请写 1.0 的名字。模型没有的名字会在加载时丢掉,并给一条警告。没有 weights 的锚点就是素脸。

固定的行为,不用配置。

  • 嘴型:响度驱动 aa。
  • 眨眼:由待机系统驱动 blink;sleeping 时闭眼、低头。
  • 视线:VRM 的 lookAt;头会轻微跟随,和 Live2D 一样。
  • 待机:呼吸,头和脊柱在平滑噪声上做小幅摇摆而不是循环播放,以及随机眨眼。
  • 取景:正交相机,脚在窗口下边缘,居中,上方留出字幕气泡的位置。

手势。 默认情况下,nod、shake、tilt_head 和 wave 是代码里写好的骨骼动作(bone-gestures.ts),所以任何 humanoid VRM 不用配置就能用。想给其中一个换成自己的动画,指向一个 .vrma 文件(路径相对于 avatar/):

"gestures": { "wave": { "vrma": "wave.vrma" } }

只会用到剪辑里 humanoid 骨骼的旋转,叠在站姿之上,剪辑动到的每根骨骼会在 200 毫秒内淡入淡出。视线、表情和位置仍然归角色。

Live2D

Live2D 由用户自备:DeskMate 不附带 Live2D 的运行时(Cubism Core),也不附带任何 Live2D 模型。用户自己导入 Cubism Core,来自 Cubism 5 SDK for Web(5.x 版本;不支持 6.x)。见 ADR-0010。

{
  "kind": "live2d",
  "model": "hiyori_pro_t11.model3.json",
  "gestures": {
    "nod": { "motion": { "group": "Tap", "index": 0 } },
    "wave": { "motion": { "group": "Tap@Body", "index": 0 } }
  },
  "idle": {
    "thinking": { "motion": { "group": "FlickDown", "index": 0 } }
  },
  "idleMotion": { "group": "Idle", "everySeconds": [20, 60] },
  "expressions": [
    { "name": "neutral", "valence": 0, "arousal": 0 },
    { "name": "joy", "valence": 0.7, "arousal": 0.3, "expression": "smile" },
    { "name": "sad", "valence": -0.6, "arousal": -0.4,
      "params": { "ParamEyeLSmile": { "value": 0, "blend": "overwrite" } } }
  ]
}

动作(用于 gestures 和 idle 的条目)是下面两种之一:

  • { "motion": { "group": "Tap", "index": 0 } }:model3.json 里的一个动作组;index 默认取第一个。
  • { "expression": "smile" }:模型自带的某个 .exp3.json 表情。

手势的键是 nod、shake、tilt_head、wave;待机状态是 idle、listening、thinking、speaking、sleeping。省略的就不做动画。

表情锚点可以带下面之一:

  • "expression": "<name>":模型里的一个具名表情;
  • "params": { "<ParameterId>": … }:直接写参数值,给没有 .exp3.json 的模型用。裸数字是加到参数上;{ "value": 0.6, "blend": "add" | "multiply" | "overwrite" } 的混合方式和 exp3 一样。参数每帧叠在动作之上,约 300 毫秒淡入淡出。对负面表情,请在 ParamEyeLSmile、ParamEyeRSmile 和 ParamMouthForm 上用 overwrite,否则待机动作里的笑眼会透出来。
  • 都不带:模型的素脸。

idleMotion 在纯待机时,在程序化摇摆的间隙里偶尔播放一个动作组:everySeconds 是 [最小, 最大],默认 [20, 60]。引擎自带的待机循环、正弦摇摆和自动眨眼都被关掉,换成 DeskMate 自己的程序化版本。

从零给一个新 VRM 写配置

  1. 检查模型。 在任意 VRM 查看器里打开 .vrm。留意它的许可证:DeskMate 会从文件里读 allowRedistribution(1.0)或许可证名(0.x),在有人导出角色包时用到;并列出它有哪些表情。
  2. 导入。 在控制台的角色页,新建或编辑一个角色,把形象设为VRM 或 Live2D 模型,选择这个 .vrm。DeskMate 会把它复制进 avatar/ 并写出一份 avatar.json。打开它,看看猜成了什么样。
  3. 调锚点。 十个情感词,每个建一个同名锚点,并给它 weights。模型有对应的自带表情就优先用(比如 shy 用 Blush 表情);没有就混合标准表情(happy 0.5 加 relaxed 0.3)。neutral 放在第一个。
  4. 看效果。 重启 DeskMate,或者切到另一个角色再切回来,让舞台重新加载模型。开发版里,托盘的 Debug 菜单有情感和手势两项,可以逐个试每种脸和每个手势。
  5. 可选:自己的手势。 把 .vrma 放在模型旁边,在 gestures 里引用它。

导入会生成什么

模型没有带 avatar.json 时:

  • 已知模型:当文件名包含文件夹名,且映射用到的每个动作模型里都有时,使用 assets/known-avatars/<name>/avatar.json。目前只有 Hiyori。
  • Live2D:Idle 动作组成为待机动作;模型的表情按名字(smile、sad、angry 等)匹配到情感词,外加一个 neutral 锚点。手势猜不出来,想要就手写。
  • VRM:只读 GLB 里的 JSON 块。每个情感词优先用模型里同名的表情,没有就用标准表情的固定混合,去掉模型缺的那些。手势用内置的骨骼动作。

对 VRM,作者的条款也会从 .vrm 读进 avatar.json 的 meta(标题、作者、许可证、allowRedistribution、termsUnclear)。这只是给控制台用的缓存:每次要紧的时候,DeskMate 都会重新从 .vrm 本身读条款,所以改 meta 改不了共享的结果。许可证为 Other 的 VRM 0.x 模型算不可再分发,因为它们的条款在一个程序读不了的链接后面。

内置形象的 avatar.json 还带 "builtin": true,这会让角色包存一个对它的引用,而不是存模型。

最后更新于