形象配置格式
告诉 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。用它们给锚点命名,就能得到这个行为。它们的默认位置:
| 词 | valence | arousal |
|---|---|---|
| neutral | 0 | 0 |
| joy | 0.7 | 0.3 |
| excited | 0.7 | 0.8 |
| calm | 0.4 | −0.5 |
| sad | −0.6 | −0.4 |
| angry | −0.4 | 0.8 |
| scared | −0.8 | 0.4 |
| surprised | 0.1 | 0.9 |
| shy | 0.3 | 0.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 写配置
- 检查模型。 在任意 VRM 查看器里打开
.vrm。留意它的许可证:DeskMate 会从文件里读allowRedistribution(1.0)或许可证名(0.x),在有人导出角色包时用到;并列出它有哪些表情。 - 导入。 在控制台的角色页,新建或编辑一个角色,把形象设为VRM 或 Live2D 模型,选择这个
.vrm。DeskMate 会把它复制进avatar/并写出一份avatar.json。打开它,看看猜成了什么样。 - 调锚点。 十个情感词,每个建一个同名锚点,并给它
weights。模型有对应的自带表情就优先用(比如shy用Blush表情);没有就混合标准表情(happy0.5 加relaxed0.3)。neutral 放在第一个。 - 看效果。 重启 DeskMate,或者切到另一个角色再切回来,让舞台重新加载模型。开发版里,托盘的 Debug 菜单有情感和手势两项,可以逐个试每种脸和每个手势。
- 可选:自己的手势。 把
.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,这会让角色包存一个对它的引用,而不是存模型。
最后更新于