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製アバターに対しては一般的な導入方法ではマテリアルが削減されないという問題があります。ここではその問題を回避しつつ、アトラス化とマテリアルの削減を行います。

本編

前提条件と準備

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

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

メモ: lilToonが必須の理由

 なぜlilToon前提なのかはTTT AtlasTextureの仕様をご覧ください。アトラス化にはシェーダーの制約があり、MToonからの変更先として事実上lilToonがもっとも適しているためです。

以下のシェーダーである場合、アトラス対象のUVチャンネル に指定されている UV チャンネルを使用しているテクスチャがアトラス化されます。

  • lilToon
  • Standard
  • VRCSDK StandardLite
  • VRCSDK ToonLit

それ以外のシェーダーは ITTShaderTextureUsageInformation でサポートが追加されていない場合、 Property "_MainTex" が UV0 を参照しているとし、アトラス対象のUVチャンネル が UV0 の場合にそれのみが対象になります。

メモ: MToonからlilToonに変換する方法

 MToonからlilToonへの変更についてはこちらの記事が参考になります。
 VRC VRoid Tip3 VRoidのlilToon基本設定

アバターの紹介

 作業見本としてVRoid Studioのプリセットの中から重ね着をたくさんしていて、マテリアル数が多そうなアバターを使用します。


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

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

AAO Trace And Optimizeの設定

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


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

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

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

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

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

 以上のことから、見た目を維持しながらマテリアルを統合しようとすると、5つまでなら、見た目に影響を及ぼすことなく削減できると考えられます。

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

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

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

TTT AtlasTextureによるアトラス化

準備(UIの日本語化)

 まずは操作画面は日本語の方が見やすいと思いますので日本語にしましょう。
 ツールTexTransToolMenu と進み、表示された「TTT Menu」でLanguageで「ja-JP」を選択します。


UI日本語化の手順

 ここから先のスクリーンショットはすべて日本語UIによるものです。

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

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

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


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


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

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

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

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

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


衣装と靴を選択する様子

 画像のとおりの設定が終わっていれば、シーンにはアトラス化後のアバターがプレビューで表示されています。プレビューの有効と無効を切り替えるとアトラス化されていることが分かると思います。
 ③で4096pxを選んでいますが、ここは統合するマテリアル数や元のテクスチャーの大きさで選択してください。プレビューしながらピクセル数を変更すれば、アトラス化による影響が可視化されますので、便利です。

メモ: アイランド大きさ優先度
 v0.9.xとv0.10.xの違いとして、アイランド大きさ優先度の選択方法が変わっています。以前はマテリアル(に紐付いたテクスチャー)一つひとつに対して0~1の数字を割り当てていましたが、v0.10.xでは、まず優先度別のグループを作成し、対象となるマテリアルを選択するようになっています。

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


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

 なぜかマテリアルスロットが減っていないことに気づくはずです。テクスチャーはアトラス化されていて、マテリアルも減っているはずなのになぜか23のままになっています。すでにTTTを使ったことがある方であればマテリアルが減らないことに気づいて諦めた方も多いかも知れません。

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

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

 VRoid製アバターの場合、ここが一番の重要ポイントなので丁寧に作業してください。

  1. 空のゲームオブジェクトを追加し、わかりやすい名前をつけます。
  2. 1で追加したオブジェクトに「AAO Merge Skinned Mesh」コンポーネントを設定します。
  3. 「AAO Merge Skinned Mesh」コンポーネントのスキンメッシュレンダラーに統合したいメッシュを追加します。
    • VRMを初期設定で変換した場合はBodyメッシュのみ。メッシュの統合をオフにして変換した場合は、ここで全部登録する
    • Unityでアクセサリー等を後付けしている場合は、コンポーネントのメッシュレンダラーやスキンメッシュレンダラーに適宜追加することでメッシュを統合できます
  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に登録する作業です。これは最初と同じです。ピクセル数は今回は2048でいいと思います。


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

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


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

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

メモ: マテリアル統合の考え方

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

メモ: さらなるアトラス化とマテリアルの分割

 v0.10.0では「マテリアル結合グループ」という概念が導入され、アトラス化とマテリアルの結合処理が独立しているので、マテリアルをマテリアルの設定ごとに統合しつつ、テクスチャーを1枚にする、という操作が可能になっているます。この記事はその機能が導入する前に記述した内容に対してv0.10.0の内容を一部反映しているため、最新の機能を効率よく導入はできていません。ぜひ試してみましょう。ボディースーツを使って細かい飾りや爪を重ね着していて、質感は残しつつアトラス化したいと言った場合、かなり効率よく圧縮できるはずです。

マテリアルの結合グループ
マテリアルを部分的に選択し、それらのマテリアル結合時の参照を指定することが可能です。
そのグループで選択されたマテリアルだけ別のマテリアルに結合したり、その部分だけ結合しない指定も可能です。

すべてのマテリアル結合時参照
ここにマテリアルを割り当てると、上記マテリアル結合グループによって指定されなかった(マテリアル結合グループが一つもない場合はすべて)マテリアルが割り当てたマテリアルに結合されるようになります。
すべてのマテリアルを一つにしたいときなどに割り当てることを想定しています。

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

 一般的な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のv0.9.xまで存在していたバグについて

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

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

 しかし、この問題は、v0.10.0で解消されていますので、これを機にぜひマテリアルの削減に調整してみましょう!
 非正方形のテクスチャー(目の周りやブーツ)を使用したマテリアルを気にせず統合することができるようになります。

余談

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


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

Misskeyにノート

Fediverseに共有