普段遣いのアバターと軽量化アバターをなるべく共存させたい!

はじめに

前々から話題になっていた Avatar Performance Rank がついに VRChat に導入されました。

私は既存のアバターが Poor だったのですけど、人が多い時などなるべく負荷をかけない軽量バージョンのアバターも用意しておきたいと思っていたので、いい機会なので Excellent を目指して軽量化を行うことにしました。

ただ、「普段遣いのアバター」から「軽量化したアバター」にするのは結構たいへんだったので、他の方の参考になればと思いこの記事を書きました。

Blender 編

自作アドオン ( Taremin Blender Plugin )

私は基本的にモディファイアなどはなるべく適用しない状態でモデルを作っていて、FBXエクスポートする際に自作のアドオンで以下の作業を1クリックでできるようにしています。

  • アーマチュア以外のモディファイアの適用
  • メッシュの結合
  • 首と胴体のマージ
  • 非表示オブジェクトの削除
  • 非選択アーマチュアレイヤーのボーン削除

この最後の「非選択アーマチュアレイヤーのボーン削除」という機能は「衣装きせかえ」のために用意してあったんですけど、今回は軽量化ということで「Humanoid」以外のボーンを削除できないかと考えました。

アーマチュアレイヤー

アーマチュアレイヤーを使ったことのない人も多いと思いますので、簡単に説明するとこれ(下図)です。

これで、Humanoid ボーンと耳や髪、しっぽ、衣装などのボーンをそれぞれ別レイヤーに分けます。
レイヤーの分け方はアーマチュアの編集モードにしたあとに、移動したいボーンを選択して「M」です。
もしくは下記のように「アーマチュア」→「ボーンレイヤーを変更」です。

レイヤーの移動をしても親子関係などはそのままなので安心してください。

ボーンの削除してそのままだとダメ

あとは Humanoid ボーン以外のアーマチュアレイヤーにあるボーンを削除すればOK…と思ったんですがダメでした!
ボーンを削除しても頂点ウェイトの頂点グループはそのままになっているため、頭を動かすと髪がその場にのこったりマトモに動作しませんでした。
下記のように耳のボーンを削除したのに耳の頂点ウェイトがそのままになってしまっています。

そこで、ボーンを削除するときに親ボーンがある場合は、メッシュの全頂点の頂点ウェイトを削除するボーンの頂点グループから親の頂点グループに足すようにしました。
(文章にするとわかりにくいですけど、頂点に Parent: 0.0, Child: 1.0 のウェイトがついてる時、Child を消すときに Parent: 1.0 にして Child を消すということです )

リーフボーンを追加しない

FBXエクスポート時に(デフォルトの設定だと追加するので)リーフボーンを追加してる人多いと思います。
でもVRChatではなくても特に不都合ないようなので、追加しないようにしましょう。
FBXエクスポートの「アーマチュア」から「リーフボーン追加」のチェックを外します。

Unity 編

普段使いのアバターからコンポーネントのコピーと余計なコンポーネントの削除

アバターから別のアバターに正規表現でマッチしたコンポーネントをコピーする CopyComponentByRegex というエディタ拡張を作っているのですが、こちらはアバター更新時も使用するので出来れば正規表現は触りたくない…
そこで、RemoveComponentsByRegex という正規表現でマッチしたコンポーネントを削除するエディタ拡張をつくりました!

Blenderでの作業が必要ない人などで単にコンポーネントを削除すれば軽量化できる方なども便利に使えると思います。

それはともかく、Humanoidボーンしか入っていないアバターに通常通り CopyComponentsByRegex でコンポーネントをコピーしたあと、RemoveComponentsByRegex で余計なコンポーネントを削除するという流れで、軽量化アバターができるようになりました。

あと、ここだけは個別対応になってしまうのですけど、体のメッシュにまばたき Animator をいれている場合はそこだけ RemoveComponent してあげて Excellent にしています。

おわりに

私の普段のアバター更新ワークフローの一部と軽量化アバターを作るときの作業をまとめたのですが、BlenderもUnityも今年に入ってVRChatで遊ぶために始めたのでまだまだ知識不足が多いです。
もっと良い方法などあれば @Taremin_VR まで声をかけていただけるとたすかります!

また、この説明でわからないことなどありましたらお気軽に聞いてください!