Open6

vrm(0.x)を.gltfにしたときにモーフ名が読み込まれない問題を解決する

kazu0617kazu0617

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.

https://github.com/vrm-c/UniVRM/issues/1739

VRM1.0では解決していそうです。
https://github.com/vrm-c/vrm-specification/issues/199

最新のUniVRMでgltfとして出力したり、VRMファイルをエディタにかけた後extrasの位置を一階層下に下げてあげることで認識します。
UniVRM - Import: https://github.com/vrm-c/UniVRM/pull/380
UniVRM - Export: https://github.com/vrm-c/UniVRM/pull/581

以降、手動でのやり方。

kazu0617kazu0617

手動: 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ファイルが読み込めるようになります。

kazu0617kazu0617

2. VRMをGLTFに変換

以降、上の手順でVRMファイルを読み込めるようにしているものとして扱います。
読み込めるようにしていない場合は、適宜読み替えをお願いします。

  1. VRMファイルの入っているフォルダをVSCodeで開き、VRMファイルを右クリックするとGLTF関係の拡張メニューが出てきます。ここから、Import GLBを選択してGLTFとして展開してください。GLTFを展開する際は新規でフォルダを生成することをお勧めします。
  2. GLTF(.gltf + .bin + .png)が生成されたら、.gltfファイルを開きます。
  3. 下の画像を参考にモーフターゲットの設定されているものに対し、meshes[].primitives[].extras.targetNames -> meshes[*].extras.targetNames に移動させます。




  1. 完了したら保存し、ファイルを右クリック -> [Export to GLB (Binary file)]をクリック。ファイルとしてglbが出力される画面が出るので、任意の名前に直して出力。
kazu0617kazu0617

因みに、UniVRM最新版で確認したところ、この問題は起きないようになっていることを確認しました。
というか両方に出力されるようになっていました(えらい)。
困ったら最新版で出しなおそう。
両方に出力

なくても空配列を入れている