Avatar OptimizerとTexTransToolを使ってマテリアルが増えがちなVRoid製アバターのマテリアルを減らす

  1. Home
  2. 読み物
  3. 副産物
  4. Avatar OptimizerとTexTransToolを使ってマテリアルが増えがちなVRoid製アバターのマテリアルを減らす

始めに

この記事の概要と対象者

背景

 VRoid Studioでは重ね着機能を使うことで衣装をより華やかに見せることが可能になりました。しかし、VRoid Studioの仕様上、重ね着をすればするほどマテリアルが増えるという欠点があります。
 これに対してVRoid StudioではアバターをVRMにエクスポートする際にマテリアルを減らして出力をするオプションがあります。しかし、このオプションは、元のテクスチャーの大きさを考慮せず、一律の大きさでアトラス化(テクスチャーを縮小して再配置すること)するため、特に大きなテクスチャー画像を使用する衣装の劣化が著しいほか、アウトラインの設定がなくなったりと、見た目に与える影響が大きいという欠点があり、VRoid Studio製アバターのマテリアルを減らすことに躊躇する要因となります。

 また、昨今広く使われているであろうAvatar OptimizerとTexTransToolによるアバターの軽量化は、初期設定のままではVRoid Studio製アバターにはあまり大きな恩恵がありません。(VRoid Studio製アバターの問題なのかVRM Converter for VRChatの変換結果の問題なのかは不明。)それを細かく設定してあげることで、本来の機能を発揮させ、マテリアルを削減することを目標にします。

本編

前提条件と準備

  1. VRoid Studioでアバターを編集し、VRMにエクスポートします。外部ツールを用いたボーンの統合やアッパーチェストの削除はこの段階で行いましょう。Unityで作業をする場合はこの後でもかまいません。
  2. VCCまたはALCOMからアバター向けのプロジェクトを新規作成します。
  3. 以下のパッケージを追加で導入します。必要に応じてリポジトリを追加してください。
  4. VRM Converter for VRChatを使ってVRMをVRChat向けに変換します 。
  5. すべてのマテリアルのシェーダーをlilToonに変更し、各種設定を行います。
  6. ツールからanatawa12's gist selecterを選択して、Actual Performance Windowを有効にします。

 この記事ではここまでの作業についての説明は省きますのでご了承ください。
 準備ができたら早速作業を始めましょう。

 なぜlilToon前提なのかはTTT AtlasTextureの仕様をご覧ください。lilToon以外の場合、メインテクスチャー以外はアトラス化されないので、VRMで用いられるMToonシェーダーのようにShade Colorにもテクスチャー画像が事実上必須のシェーダーは、影の描写がおかしくなるからです。

lilToon の場合

UV0 を参照しているテクスチャーであることです。 たとえば、MatCap などのUVを使用しないテクスチャや、 UVMode が UV1~3 のテクスチャは対象に含まれません。

それ以外のシェーダーは AtlasShaderSupport でサポートが追加されていない場合
Property "_MainTex" のみが対象になります。

アバターの紹介

 今回は、私が普段使っているアバターではなく、VRoid Studioのプリセットの中から重ね着をたくさんしていて、マテリアル数が多そうなアバターを使用します。


サンプルDさんのパフォーマンスランク。

 マテリアル数は23となかなかの重さです。

 まずは必要最低限の準備として「AAO Trace And Optimize」コンポーネントをアバターのルートに設定してください。そしてプレイモードに入って見ましょう。


AAO Trace And Optimizeコンポーネント適用前後による変化

 とりあえずつけておけと言われる「AAO Trace And Optimize」コンポーネントですが、いろいろ後付けで改変したアバターには効果がありますが、ほぼ素に近いアバターには効果がほとんどありません。必要最小限(といっても無駄はありますが)で構成されているので当然と言えば当然です。

マテリアルの削減を理解する

 マテリアルの削減、もっと言えばマテリアルスロットの削減とは、メッシュを結合して、そのメッシュのマテリアルスロットを削減するためにマテリアルを統合し、そのためにテクスチャーをアトラス化すること、と言い換えることができると思います。この辺はあまり詳しくないので間違っていたらごめんなさい。
 とにかく、メッシュを結合、テクスチャー画像を統合しつつ同じ設定のマテリアルを統合、という流れになります。
 この時、VRoid製アバター(VRMを取り込んだアバター)は、取り込み時の設定次第ですが、初期設定のまま変換した場合はメッシュがひとつになっていますので、後はアトラス化してマテリアルを統合するだけです。

 マテリアルの結合は同じ設定のマテリアル同士を結合すると見た目への影響が少ないです。VRoid Studioのマテリアル削減機能で2つまでしか減らせない設定になっているのは、透過ありとそれ以外でマテリアルを統合しているからでしょう。さらに言えば、アウトラインの設定がおかしくなるのは、ありとなしのどちらかに統一する必要があるからと考えられます。

 以上のことから、見た目を維持しながらマテリアルを統合しようとすると、ざっくりと作業すれば5種類となるでしょうか。

マテリアル番号 テクスチャーの扱い アウトライン
1 半透明 なし
2 カットアウト なし
3 カットアウト あり
4 不透明 なし
5 不透明 あり

 実際には、半透明同士の場合、レンダキューの設定値が違えばマテリアルを分ける必要もありますし、髪の毛はちょっと特殊なのか、まとめるとうまくいかないので、見た目を維持したまま5種類まで減らすのは事実上不可能と考えています。

 効率的に減らすにはトライアンドエラーの慣れが必要ですので、とりあえずやってみましょう。

TTT AtlasTextureによるアトラス化

 「AAO Trace And Optimize」コンポーネントをアバターのルートにつけていない場合は、この時点で忘れずに設定しておいてください。

準備(UIの日本語化)

 まずは操作画面は日本語の方が見やすいと思いますので日本語にしましょう。
 ツール→TexTransTool→言語→JA でコンポーネントが日本語になります。


UI日本語化の手順

 余談ですが、英語の方が検索したときに検索しやすいということでUnityを英語で使うことを推奨する記事も見かけますが、個人的には調べるときだけ英語に脳内変換(あるいはIMEで変換)すればいいと思っているので、基本的に日本語環境で作業してますので、スクリーンショットはすべて日本語UIです。

アトラス化するための設定を行う

 TexTransTool(以後「TTT」)は公式のドキュメントが非常に丁寧に作られているので、そちらも参照してください

 まずは、TTT AtlasTextureコンポーネントを追加します。


右クリックメニューからTTT AtlasTextureを選ぶ。


右クリックメニューからTTT AtlasTextureを選んだ後の状態

 追加されたオブジェクトを選択すると、インスペクターにTTT AtlasTextureコンポーネントが表示されていて、マテリアルが列挙されていることが分かります。

アトラス化するマテリアルを選ぶ

 前述しましたが、同じ設定のマテリアルを選ぶのが基本的な考え方になります。VRoidの場合、衣装と靴は同じ設定になっていますので、これはひとつにまとめることができます。重ね着によって大量のマテリアルを消費している衣装がひとつになるので、一気に減らすことができます。

 TTT AtlasTextureコンポーネントのマテリアルを見ながら、チェックボックスにチェックを入れていきます。


衣装と靴を選択する様子

 画像のとおりの設定が終わっていれば、シーンにはアトラス化後のアバターがプレビューで表示されています。プレビューの有効と無効を切り替えるとアトラス化されていることが分かると思います。
 ②では4096pxを選んでいますが、仮に2048にすると画像が粗くなると思います。使っているアバターが2048でも問題なさそうであれば2048でもいいでしょう。ここまで重ね着をすることがないので、私は2048しか使ったことがありません。統合するのが4~6マテリアルぐらいなら2048でも気にならないと思います。
 よく言われることですが、2048と4096は幅は2倍ですが面積は4倍ですので、VRAMも4倍消費することになります。

 これで設定は終わりましたので、早速プレイモードにして、Actual Performance Windowを見てみましょう。


プレイモードに入ってもマテリアル数が減っていない

 はい。
 なぜかマテリアルスロットが減っていないことに気づくはずです。テクスチャーはアトラス化されていて、マテリアルも減っているはずなのになぜか23のままになっています。
 気になる方はNDM Frameworkの機能でManual Bakeしてみてからプレイモードに入って見てください。マテリアルスロットの数は変わらず23のままになっているかと思います。

 TTT AtlasTextureコンポーネントのドキュメントでは、「メッシュをマージしながらマテリアルスロットも削減できるAnatawa12/AvatarOptimizerのTraceAndOptimizeやMergeSkinnedMeshとの併用を強く推奨します。」となっており、次に紹介するAAO Merge Skinned Meshコンポーネントのドキュメントでも「Trace And Optimizeが自動で同様の処理を行うため、大抵の場合、このコンポーネントを使用する必要はありません。」となっていることから、多くの場合は、「AAO Trace And Optimize」と「TTT AtlasTexture」だけでマテリアルスロットが統合されると思うのですが、VRoid製アバターの場合はうまくいきません。

 余談ですが、私はVRoid以外のアバターを持っていないので、この機能が一般的なVRChat想定アバターでうまくいっているか分かりません。なお、VRoid製アバターとしていますが、実際にはVRM Converter for VRChatで変換したアバターのではないかと思いますが、真実はいかに。

 閑話休題。
 とにかくこのままではアトラス化した意味がないので、おまじないをする必要があります。

おまじないをしてマテリアルスロットを統合する

 ここが一番の重要ポイントなので丁寧に作業してください。

  1. 空のゲームオブジェクトを追加し、わかりやすい名前をつけます。
  2. 1で追加したオブジェクトに「AAO Merge Skinned Mesh」コンポーネントを設定します。
  3. 「AAO Merge Skinned Mesh」コンポーネントのスキンメッシュレンダラーに統合したいメッシュを追加します。
    (VRMを初期設定で変換した場合はBodyメッシュのみ。メッシュの統合をオフにして変換した場合は、ここで全部登録する)
  4. 害はないと思うので、とりあえず「同名のBlendShapeを統合する」にしておく。
    (アバターやプロジェクトの構成によりけりだと思うのですが、表情が動かなくなったり、指が動かなかったりする時は、ここを「同名のBlendShapeを統合する」にすると直ったので、私はあらかじめこの設定にしています)


AAO Merge Skinned Meshコンポーネントを設定する

 設定できたらプレイモードに入ってみましょう。


マテリアルは減ったけど…

 マテリアルスロット数は激減しました。9このマテリアルを1個に統合したので、8個減っていると言うことがよくわかります。ですが、NDMFコンソールに謎のエラーが表示されています。「直すには」をクリックすると原因と直し方が表示されていますのでそれに従いましょう。

 アバターのルートに「MA Mesh Settings」コンポーネントを追加します。このコンポーネントは、このコンポーネントがあるオブジェクトの配下にあるオブジェクトの設定を上書きするので、アバターのルートに設定するのがお勧めです。
 コンポーネントを追加したら、Anchor OverrideとBoundsを設定します。どちらもTransform(位置だけ参照)なのでどんなオブジェクトでもいいですが、Anchor Overrideは頭(Head)か胸(Chest)、Boundsは背骨(Spine)がいいと思います。


MA Mesh Settingsを設定する

 よっぽどアバターが大きくない限りは、Boundsの範囲(シーンに表示されている白い箱)はルートボーンにSpineを設定しただけで問題ないと思いますが、アバターが白い箱をはみ出る場合は、アバターが収まる大きさまで「範囲」を広げてあげましょう。そうしなければ他の人からアバターの一部が見えなくなります。

 設定が終わったらプレイモードに入ってみましょう。NDMFコンソールのエラーがなくなったはずです。

もっとマテリアルを減らす

 最も簡単なアトラス化は終わってしまいましたので、ここから先は応用編です。最初と同じようにTTT AtlasTextureコンポーネントを追加しましょう。


設定が違うマテリアル達

 さて、マテリアルの統合は同じ設定が基本としましたが、画像では4つのマテリアルに焦点を当てています。設定だけで見たら共通点もありますが、見た目に影響を与えずすべてをひとつに、というのは不可能に見えます。唯一、口内と白目はまとめられそう、というのは分かるでしょう。

現在のシェーダー設定
部位 描画 カリングモード アウトライン ノーマルマップ 考察
カットアウト 片面描画 あり あり 統合したら見た目に影響が出る…?
不透明 片面描画 あり なし 統合したら見た目に影響が出る…?
白目 不透明 片面描画 なし なし この二つは統合できそう
口内 不透明 片面描画 なし なし

 ですが、これらのマテリアルは一工夫することで、同じ設定のマテリアルにすることができます。

シェーダー設定の変更案
部位 描画 カリングモード アウトライン ノーマルマップ
カットアウトのまま 片面描画のまま 「あり」のまま 「あり」のまま
カットアウトに変更 片面描画のまま 「あり」のまま 「あり」に変更して紫一色の画像を登録する
白目 カットアウトに変更 片面描画のまま 「あり」に変更してマスクに黒一色の画像を登録する 「あり」に変更して紫一色の画像を登録する
口内 カットアウトに変更 片面描画のまま 「あり」に変更してマスクに黒一色の画像を登録する 「あり」に変更して紫一色の画像を登録する

 という具合です。どうでしょうか。すべて同じ設定のマテリアルになりましたね。

 ここで着目する点は、

ということです。
 ついでに言えば、ここでは設定していませんが、「影」の設定も、マスク画像で制御できるかつマスク画像も含めてアトラス化されるので、影の設定のあり・なしも統合することができます。
 なお、片面描画と両面描画は両面描画に統一できる場面もあると思いますが、片面描画は負荷軽減に役立つので、両面描画にすることでパフォーマンスランクには影響がないものの負荷は上昇します。マテリアルスロットの削減による負荷軽減とと、カリングによる負荷軽減、どちらの影響がより大きいかは分かりませんが、どっちにするかは考え方次第でしょう。

 ちなみに、マテリアルの設定がそれぞれ異なる場合、どれかひとつのマテリアルの設定が採用されるそうです(何回か試した限りでは、TTT AtlasTextureのマテリアルリストのより上にある方っぽい)。

結合時マテリアルの参照

結合時にマテリアルの設定を参照できる機能です。
何も設定されていない場合、アトラス化対象のマテリアルの不定などれか一つが使用されます。

 話が逸れましたので戻りましょう。
 早速マテリアルの設定を上の表のように変更(統一)して、TTT AtlasTextureに登録してあげましょう。

 画像は白目の場合です。
 描画モードをカットアウトに変更し、ノーマルマップを有効にして紫色の画像を登録、輪郭線を有効にして黒色一色の画像をマスクに登録します。


設定を揃えつつ、マスク画像等で実質的に無効化する

 設定を揃える事ができたら、TTT AtlasTextureに登録する作業です。これは最初と同じです。ピクセル数は今回は2048でいいと思います。


設定を揃えたら統合対象に選ぶ

  設定が完了したらプレイモードに入ってみましょう。


4つのマテリアルを1つにしたのでマテリアルスロットが3個減って12個になった

 ここまで来るとマテリアルスロットは12個になりました。最初が23個でしたので、ほぼ半分になりましたが、見た目の劣化はほとんど感じないと思います。

メモ

 今回は服と靴を一括で一つのマテリアルに統合しましたが、lilToonにシェーダーを変更した時点で、アウトラインの色を個別に変えたり等、シェーダーの設定が違う場合は、別々のマテリアルにしなければ見た目が変わってしまいます。このあたりは目標とするマテリアル数と見た目の変化を天秤にかけながら設定する必要があります。
 私はやったことがありませんが、体、顔、服、靴はカットアウト、両面描画に揃えられるはずなので(アウトラインとノーマルマップは適宜対応)、これらも一つのマテリアルに統合することができるはずです。

もっともっと統合しよう?

 一般的なVRoid製アバターの場合、眉、まつげ、瞳の3つはカットアウトあるいは半透明に統一した上で統合できます。
 ただ、サンプルDの場合、眉とまつげがレンダキュー違いで3層に分れているため、これを同じ設定にしてしまうとレンダキューの関係で表示が乱れるのでやめておいた方が無難と感じました。
 瞳の上にハイライトが半透明で乗るので、眉・まつげ・瞳を半透明に統一した上で統合した場合は、ハイライト側のレンダキューの設定に気をつけましょう。

 髪の毛のマテリアルは、元の設定によると思うのですが、統合できそうに見えて実際に統合すると表示が変わってしまいますので、うまく行かないことの方が多いと思います。VRoid Studioで編集できるテクスチャーのオフセットが悪さをしているような気がします。

 今回は、瞳、地毛、尻尾は設定が近かったので、半透明、片面描画、ノーマルマップあり、輪郭線なし、に設定を統一して統合してみました。


10個になって半分以下になったマテリアルスロット

 元々23個あったマテリアルが10個まで減りました。
 VRoid Studioのマテリアル削減機能よりも高品質のままマテリアルを削減できていると感じられるでしょう。

VRoid Studioと比較してみよう

 VRoid Studioでマテリアル数12で出力した(実際には9になった)アバターを横に並べて、どのぐらい違うか見てみましょう。


マテリアル数は10と9でほぼ変わらないけど

 設定したのはマテリアル数12なので、VRoid Studioで変換したアバターも綺麗に削減されていますが、衣装の劣化はさることながら、前髪に設定していないアウトラインが設定されてしまい、描画に影響が出ていますね。一方Unityで設定した方は元の見た目のまま、マテリアル数を削減できています。
 これ以上減らすのはVRoid StudioでもUnityでも見た目に影響が出てしまいますが、影響の度合いはUnityで減らした方が少ないのでは、と思います。

最後に

TTT AtlasTextureの既知のバグについて

 最後になりますが、TexTransToolのTTT AtlasTextureコンポーネントには、現在、VRoid製アバターと相性が悪い既知のバグがあります。(このバグはTwitterとMisskeyでつぶやいたところ、TTTの開発者に偶然見つけていただき、その後のやりとりによってバグとして認められ現在はissueに登録されています)

AtlasTexture に 非正方形なテクスチャーを使った際に Padding の計算が正しくできておらず、ゆがむ

 VRoidには非正方形なテクスチャーが多用されており、この影響をもろに受けます。一番分かりやすいのは、白目、眉、まつげで、これらをアトラス化する設定にしてプレビューの有効・無効を切り替えると、有効にしたときに横方向に若干広がっていることに気づきます。最初にアトラス化する対象として選んだ靴も縦長のテクスチャーなのでこの影響を受けます。
 とはいえ、次期バージョンで修正予定となっていますので、遠くない未来に改善されると考えています。

 細かな違いなので見比べない限りは分かりませんし、修正に備えてマテリアル統合の練習をしておいてはいかがでしょうか。

余談

 Ringoさんのウェブサイトで公開されている「NEOKET用スクリプト」を使ってボーンを統合しつつ、上半身だけコライダーを再設定した結果、Poorまで下げることに成功しました。これならベリプアバター禁止のイベントにも参加できますね。
 突き詰めればもっとパフォーマンスランクをあげることができそうですが、お手軽な設定でもここまでできるという事例を最後に紹介して終わります。


スフィアコライダーなんて捨ててしまおう

Misskeyにノート

Fediverseに共有