Rise of ErosモデルをVRMに変換してみた

# はじめに

Rise of Eros(以下、RoE)というゲームのキャラクタの3Dモデルをネットで配布しているサイトを見つけました。
そのモデルファイルをVRMファイルに変換しましたので、どういう方法で行ったか、問題点は何かを説明します。
Rise of Erosは18禁のゲームなので、ご注意ください。

# YouTube動画

YouTube動画にも変換手順をまとめました。

[RoEモデルをVRMに変換してみた](https://youtu.be/QUcZ7GklAHY)

# モデルの配布サイト

PatreonというサイトでLezisellという方がRoEのXPSモデルを配布していました。

[Patreon (Lezisell)](https://www.patreon.com/lezisell/posts)

15ドル払ってContractorというメンバーシップになるとモデルをリクエストすることもできます。
RoEのモデルはいくつかアップされていました。PythonManは、AlanaのSpirit Detectiveというモデルが欲しかったのですが、アップされていませんでしたので、15ドル払って作成してもらいました。
この方とは、専用のDiscordで問い合わせすることができます。
PythonManは、初めルールが分かっておらず、対応できるという事でしたいので、いきなり15ドル払ってしまいましたが、月の初日にリクエストしないといけないようで、次の月の分の15ドルも払って、結局、合計30ドル払いました。
月の初日に1度だけ払えば良かったようです。

## モデルファイルに関して

このゲームは、スマホ版以外にもSteam版があります。
Steam版では、AssetStudioなどのフリーのツールを使用すればモデルファイルは抽出できる場合があると思います。
PythonManも確認したところ、OBJファイルやテクスチャファイルは見つかりました。
ボーン情報のファイルは、恐らくUnityの形式になっており良く分かりませんでした。
Blenderや他のツールを駆使すれば、自力でも出来るのでしょうが、現在のPythonManの知識だと敷居が高く、作成(抽出)を依頼するという事で解決しました。

# 変換手順に関して

変換手順は以下の通りです。
アドオンの情報は上記のYouTube動画を参照ください。

1. BlenderのXPSとPMX用のアドオンをインストール
1. BlenderでXPSをインポート
1. BlenderでXPSをPMXにコンバート
1. BlenderでPMXをエクスポート
1. 自作のPythonプログラムでPMXをVRMに変換
1. 向きやサイズを確認
1. Blenderで再度、向きやサイズを調整してPMXをエクスポート
1. 自作のPythonプログラムで再度、PMXをVRMに変換

## Pythonの使用ライブラリ

自作のPythonプログラムでは、特殊なライブラリは使用せず、Pillow、json、numpyなどの一般的なライブラリのみを使用しています。
但し、PMXファイルを読み込むのに、Asset Import Library (Assimp)というライブラリを使用してます。
この辺りの使用方法は、拙著『PyOpenGL入門 [基礎編]』にまとめています。

## PMXを経由した理由

BlenderはVRMのアドオンなどもあるのですが、XPSを直接GLTFやVRMに変換せず、PMX経由にしたのは、テクスチャが外れてしまうからです。
また、VRMに変換すると、ボーンマッピングが必要になり、PythonManはBlenderの操作に慣れていないため、うまく出来てませんでした。
そのため、たまたまうまくいったPMXを使用する事にしました。
やり方さえ分かれば、直接GLTFやVRMに変換できるかもしれません。
XPSをPMXにすると、Blender上でテクスチャの品質が落ちているような表示になりますが、この辺りは、今のところよく分かっていません。

## UniVRMに関して

PMXをVRMに変換するには、UniVRMを使用する事も出来ます。
実際、UniVRMでも試しましたが、顔の眉毛の部分などの表示がおかしくなりました。
自作のPythonプログラムを作成して原因が分かったのですが、JSONのmaterialの中にalphaModeというプロパティがあります。
このプロパティはテクスチャを処理する場合に、テクスチャの色をどのように決定するかを指示します。
UniVRMで変換すると、この値がデフォルトで全てOPAQUEになっていました。
基本的に、全てMASKにするとうまくいきました。
もしかすると、半透明のテクスチャを含む場合は、BLENDなどにする必要があるかもしれません。
ちなみに、UniVRMで値を変更する方法はよく分かりませんでした。

![alphaMode.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629087/8d664d0a-24a0-1366-4b0f-a1d9b3220330.jpeg)

あとは、ボーンの関連付けですが、いったんUniVRMで変換して、作成されたVRMファイル内のJSONデータのVRM内のhumanBonesデータをテキストファイルに抽出して、そのテキストファイルのデータを自作のPythonプログラムでファイルを指定して使用するようにしました。
また、Jawボーンが入っていると何故か口が開いた状態になってしまいますので、Jawボーンのマッピングは削除しました。

![humanBones.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629087/58c86f1d-b966-18d2-21c4-b9870b470128.jpeg)

![bones_json.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629087/e99268f0-c2e9-bb6e-fcef-17bc5c4a8d55.jpeg)

あとshaderは、VRM_USE_GLTFSHADERを使用しました。
VRMのシェーダは、Unlit、PBR、MToonの3つありますが、VRM_USE_GLTFSHADERを使用すると、VRMファイルがGLTF標準のPBRシェーダを使用することになるようです。
この辺りは、PythonManはまだ勉強不足なところです。
ちなみに、UniVRMではMToonシェーダのデータが作成されましたが、UnlitやPBRも選択できるようです。

![shader.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629087/51e5dabf-3e71-2802-05f8-61b049694639.jpeg)

# エラーに関して

自作Pythonプログラムで変換は出来たのですが、VRMはGLTFベースなので、いくつかエラーが発生しました。
重要なのは、JSONやバイナリデータを4バイト単位に整列させる必要があるのと、アクセサのオフセットで4バイト単位にしないといけないことです。
このエラーは、ブラウザで動くGLTFのビューワなどで確認する事が出来ました。

[glTF Viewer](https://gltf-viewer.donmccurdy.com/)

# どこまで変換できたか

とりあえず、以下の2点は対応できました。

1. モデルを動かす
1. VRM Spring Boneを付ける

以下はまだできていません。

1. シェーダ(材料)をきちんと設定する
1. 目パチや口パクや怒りなどの表情を設定する
1. 手足が衣服を貫通しないように設定する

表情設定は、mesh内のtargets(モーフターゲット)で頂点の変位情報を保持しておき、VRM内のblendShapeGroupsで関連付けると思います。
targetsデータは、Blenderのシェイプキーで作成できると思いますが、まだBlenderに慣れておらず、今回は断念しました。

![targets.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629087/112de89e-01ef-03f1-d921-e0202eff4374.jpeg)

![targets2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/629087/ae41c2e5-b2aa-5625-dc3a-cbad6b69c56d.jpeg)

貫通の設定は、髪の毛や手足が動いた時に、服に貫通しないように設定します。
UniVRMだと、VRM Spring Bone Collider Groupで設定出来るようです。
この辺りは難しそうなので、後回しにしました。

あと本当は、声も再現したかったのですが、VallExというアプリを試しましたが、声の品質の問題などでとりあえず断念しました。

# おわりに

Pythonの自作プログラムを作成したのは、UniVRMの使用方法が難しかったからです。
自作プログラムは、まだコマンドラインのプログラムですが、最終的にはGUIを付けてフリーソフトとしてリリースしたいと思っています。
時間がかかりそうなので、実現できるかどうかも今のところ不明です。

RoEというゲームでは3Dのモデルが良く出来ています。
このゲームをきっかけに、今は、Unityでのゲーム作成以外に、3Dモデル作成や変換にも興味を持っています。
VRM以外にもVRChatという形式もあるのですが、とりあえずVRMに興味を持っています。
BlenderやUnityの勉強が必須なのですが、今は体調の関係で色々と停滞しています。
時機を見て、少しずつでも再開したいと思っています。