vrm(0.x)を.gltfにしたときにモーフ名が読み込まれない問題を解決する
VRM(0.x)をGLTFにしたときにシェイプキーが各種DCCツールでついてこない問題、
どうやらVRM0.x時の当時はこっちが正解だったけども、その後gltf側の仕様が定まる中で
定義に合わなくなっていったっぽいです。
vrm-0.x は primitive.extras.targetNames に記録するという仕様です。
https://github.com/vrm-c/vrm-specification/tree/master/specification/0.0#morph-target-information
作った当時、すべての primitive が同じ morphTarget を持たない場合を想定していたためです。
今バージョンの glTF には下記の文言があります。
All primitives MUST have the same number of morph targets in the same order.
VRM1.0では解決していそうです。
最新のUniVRMでgltfとして出力したり、VRMファイルをエディタにかけた後extrasの位置を一階層下に下げてあげることで認識します。
UniVRM - Import: https://github.com/vrm-c/UniVRM/pull/380
UniVRM - Export: https://github.com/vrm-c/UniVRM/pull/581
以降、手動でのやり方。
手動: VSCodeに cesium.gltf-vscode を入れます。
1. VRMを強制的に読み込ませる
やり方としては2通りあります
- VRMファイルをGLBファイルにリネームして読み込ませる…毎回変更が必要なため面倒ですが下のパッチを当てる必要はないです。わからない場合はこっち。
- VRMファイルも読み込めるようにパッチを当てる…流し込めるようにパッチを当てます
上で %Userprofile%\.vscode\extensions\cesium.gltf-vscode-2.3.16
(2022/12/21当時)
package.jsonに以下のパッチを当てる
diff --git a/package.json b/package_vrm.json
index e01009a..8e6748f 100644
--- a/package.json
+++ b/package_vrm.json
@@ -317,12 +317,12 @@
},
{
"command": "gltf.importGlbFile",
- "when": "resourceExtname == .glb",
+ "when": "resourceExtname == .glb || resourceExtname == .vrm",
"group": "glTF"
},
{
"command": "gltf.validateFile",
- "when": "resourceExtname == .gltf || resourceExtname == .glb",
+ "when": "resourceExtname == .gltf || resourceExtname == .glb || resourceExtname == .vrm",
"group": "glTF"
}
],
out\src\extension.jsに以下のパッチを当てる
diff --git "a/out\\src\\extension.js" "b/out\\src\\extension_vrm.js"
index 628381f..29bb351 100644
--- "a/out\\src\\extension.js"
+++ "b/out\\src\\extension_vrm.js"
@@ -459,12 +459,12 @@ function activate(context) {
//
context.subscriptions.push(vscode.commands.registerCommand('gltf.validateFile', async (fileUri) => {
if (typeof fileUri === 'undefined' || !(fileUri instanceof vscode.Uri) ||
- !(fileUri.fsPath.endsWith('.glb') || fileUri.fsPath.endsWith('.gltf'))) {
+ !(fileUri.fsPath.endsWith('.glb') ||fileUri.fsPath.endsWith('.vrm') || fileUri.fsPath.endsWith('.gltf'))) {
const options = {
canSelectMany: false,
openLabel: 'Validate',
filters: {
- 'glTF Files': ['gltf', 'glb'],
+ 'glTF Files': ['gltf', 'glb', 'vrm'],
'All files': ['*']
}
};
これでVRMファイルが読み込めるようになります。
2. VRMをGLTFに変換
以降、上の手順でVRMファイルを読み込めるようにしているものとして扱います。
読み込めるようにしていない場合は、適宜読み替えをお願いします。
- VRMファイルの入っているフォルダをVSCodeで開き、VRMファイルを右クリックするとGLTF関係の拡張メニューが出てきます。ここから、Import GLBを選択してGLTFとして展開してください。GLTFを展開する際は新規でフォルダを生成することをお勧めします。
- GLTF(.gltf + .bin + .png)が生成されたら、.gltfファイルを開きます。
- 下の画像を参考にモーフターゲットの設定されているものに対し、
meshes[].primitives[].extras.targetNames
->meshes[*].extras.targetNames
に移動させます。
- 完了したら保存し、ファイルを右クリック -> [Export to GLB (Binary file)]をクリック。ファイルとしてglbが出力される画面が出るので、任意の名前に直して出力。
実際にこの手法を施したRefletちゃんをVroidHubに公開しています。
Vroid Hubでは名称を見ることが出来ないため不明ですが少なくともこの作業の影響でVRMとして認識されなくなる、ということはないと判断しています。
因みに、UniVRM最新版で確認したところ、この問題は起きないようになっていることを確認しました。
というか両方に出力されるようになっていました(えらい)。
困ったら最新版で出しなおそう。
毎回充てるのも大変だなーとなったのでPR出しました。