備忘録 UniVRMでVRM0.xのモデルをURPで使う方法

# はじめの駄文
VRMってなんだかよくわかんないですよね。
VRM0.xとVRM1.0のモデルがあったり、0.x→1.0のみの変換しかサポートされないと思いきや、Blenderで強引に1.0→0.xに下げられたり。
VRoidHubで公開すれば表示順が正しく反映されず、Blenderでは透過マテリアルの描画順は考慮されず、透過マテリアルにアウトラインがあると破綻し、VRMドキュメントは情報が少なくかつ記事がWIPのままだったり……。
今回は、VRoidStudio→Blender→Unityという流れで作ったモデルをゲームに使おうとし、色々と試行錯誤した上でようやくインポートできましたので、その手順を書き残しておきます。

# VRMのバージョン問題
VRMにはVRM0.xとVRM1.0の2バージョンが存在します。簡単にそれぞれの特徴をまとめると次のとおりです。
### VRM0.x
- 前からあるので対応しているソフトが多い(3tene、VSeeFaceなど)
- UniVRMで読み込むと全部のデータが展開される
- **URP非対応**(MToonシェーダーのURP対応版が存在しない)
### VRM1.0
- 新しい形式のため対応ソフトが少ない
- よくわからんけどなんか色々変更されてるらしい

https://vrm.dev/vrm1/changed.html

- ライセンス条項が拡充されていてより細かい指定が可能に
- UniVRMで読み込むとモデルにデータが紐付けられていて必要なものだけ展開できる
- **URPに対応**(VRM10/Universal Render Pileline/MToon10が対応しているシェーダー)

個人的にはVRM1.0のほうがライセンスを細かく指定できますし好みなのですが、なにより対応ソフトが少ないのでVRM0.xのモデルを作らざるを得ないのが現状です。
もちろん限られた状況で自分だけが使うのならVRM1.0で作るので良いのですが、VRoidHubで色んな人が使えるように公開するなどした場合、VRM1.0ではほとんどの人が使用できなくなってしまいます……。

Unityのレンダーパイプラインについては、ShaderGraphが使える、ポストエフェクトを調整しやすい、動作が軽いなどの点でURPが好きであり、Unityでのゲーム制作は基本URPで進めたいのです。
しかし、VRM0.xモデルはURPに非対応。うーん、ジレンマ。
ということで、VRM0.xのモデルをなんとかしてURPで使いたい、というのが自分の現状なのです。

# VRM0.xをURPで使う方法
わかってしまえば簡単なことではありますが、VRM0.xのモデルを色々いじった結果URPで正常に表示できたので、その手順を紹介します。
## 1. UniVRMの導入
UnityでVRMを扱うため、UniVRMをプロジェクトに導入します。

https://github.com/vrm-c/UniVRM/releases

この際、**VRM 1.0 Import/Export**版(パッケージ名がUniVRMではなくVRMで始まる方)のパッケージを導入してください。

## 2. VRM0.xモデルをUnityプロジェクト内に配置
今回はAssets/Modelsフォルダに.vrmファイルを配置します。
VRM1.0の入出力版のUniVRMのため、配置しても自動でモデルデータに変換されません。
![スクリーンショット 2023-12-24 124246.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102419/df29d383-548e-c82d-384e-d0e1f066c12c.png)

## 3. VRM0.xモデルを1.0に変換
VRM 1.0 Import/Export版のUniVRMの機能に、0.xから1.0に変換する機能があるようです。
VRM 0.0 Import/Export版にはないので注意！
([公式ドキュメント](https://vrm.dev/univrm1/migrate_vrm0/migrate_editor.html)では`VRM-0.XXX.0_faa1.unitypackageの機能です。`って書いてありますが、この記事を書くまでファイル名がUniVRMで始まるものが0.x版でVRMで始まるものが1.0版なんて気づきませんでした。そもそも今のバージョンではfaa1って書いてないですし……。そこら辺一切説明がないのでほんと不親切だと思います)
というわけで、UnityのProjectビューから.vrmファイルを選択しインスペクタを見てみると、なにやら書いてあるのがわかります。
Migrate To Vrm 1にチェックを付け、[Apply]を押しましょう。
![スクリーンショット 2023-12-24 124937.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102419/35b90bcf-8de6-92cf-1dd4-29f85e6d7a5b.png)
これでモデルがVRM1.0に変換されました！やった！
**……と思いきや、モデルが真っピンクです。**
![スクリーンショット 2023-12-24 125118.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102419/7b2b2b15-d3a6-9d05-ff3a-15299ffb1774.png)
URPを使っているうちに、この光景にはもうだいぶ見慣れてしまいました。シェーダーがURPに対応していないようです。

## 4. マテリアルの抽出とシェーダーの変更
VRM1.0の場合、デフォルトでマテリアルがモデルデータに内蔵されているため、このままでは編集ができなくなっています。
ということでモデルテータからマテリアルを抽出しましょう。
モデルデータを選択し、[Materials]を押してから[Extract Materials And Textures ...]を押します。
![chrome_tcu7P028kY.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102419/7786b6c5-1ddb-ec59-a6e2-f3ae8333512b.png)
するとこのように、`モデル名.Materials`フォルダが作成され、中にモデルのマテリアルが並べられました。
![スクリーンショット 2023-12-24 125721.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102419/124d1082-bb81-8651-da0a-046d927705ea.png)
後はこのマテリアルを全選択して……
![スクリーンショット 2023-12-24 125827.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102419/db05a857-510d-2af8-86f8-32998361451b.png)
Shaderを**VRM10/Universal Render Pipeline/MToon10**に変更します。
![スクリーンショット 2023-12-24 125918.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102419/5a5340b6-4881-d201-7a11-579d1a52c078.png)
するとようやくまともに表示されました。なんかデフォルトのBloomがかかってて色合い違うけど。とりあえずばんざーい！！
![スクリーンショット 2023-12-24 130044.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102419/4bae54dc-0d1b-47e9-3e93-8219d5374605.png)

**……これで終わりだと思っていたのか？**
## 5. Transparentなマテリアルの描画順を調整し直す
本当に原因がわからないのですが、**なぜか**描画順が反映されません。
RenderQueue Offsetの数値が狂ってるわけでもなく、本当に何故か適用されないのです。
MToonにステンシルの表現がなく、それでも眉毛を髪に透かす表現をしたかったので、髪・眉のマテリアルをTransparentにした上でRenderQueue Offsetをいじっています。しかし上の画像ではよく見ると前髪に眉が隠れています。
ということで、RenderQueue Offsetを設定し直しましょう。
といっても、一度数値を消して、適当に変えてからもう一度元の数値に戻すだけです。最前面に表示される眉はRenderQueue Offsetの値は0だったので、0→-1→0という風に書き変えました。
すると……
![スクリーンショット 2023-12-24 130405.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1102419/3d9866cb-f813-9186-133a-95f3d68e68c0.png)
**できた！！！！！！**

# どうしても直らない問題(追記 2024/04/13)
服などあらゆるマテリアルのアウトラインが表示されないことに気づきました。
SRPのUniVRMでは正常に表示されていましたし、~~どう設定しても直らないので、おそらくURP版MToon10シェーダーの不具合、あるいはまだ対応していない仕様のようですね。~~

:::note info
(追記 2024/04/13)
URPのRenderer FeatureにMToonのOutlineの描画機能を追加することで描画されるようです。
:::

https://qiita.com/OmO_ti/items/bc4080b01aa3fd011155

# おわりに
まだ問題があるかもしれませんが、とりあえず目につく不具合はできる限り修正することができました。
それでも、まだシェーダーの問題は完全には解決されていなかったりします。
URPの機能はかなり増強されてきたものの、SRPを軸に開発しているところは未だに多いようで……早くURPに完全移行される日が来ることを願っています。
とりあえず、MToon10ではなくUnityToonShader3でも試してみるかな……。

余談ですが、今回使用したモデルはすしわかめさん制作のウディタ製ゲーム「おばけのロッソ」の主人公を3Dで再現した、自作二次創作モデルです。
現在DEMO版として3章まで公開されていますがとても面白い作品です。
二次創作にかなり寛容ですし、とてもありがたいですね。
興味のある方はぜひ。

https://sushiwakame518.wixsite.com/rossotheghost

https://hub.vroid.com/characters/1495577083607569151/models/2019522577531042195

おわり。