17
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【VRChat】n番煎じで送るアバター最適化TIPS

Last updated at Posted at 2024-06-01

注意

今回の記事は、VRChat公式が推奨する手段と、私が普段最適化を行う上で心がけている項目をまとめたものです。
いつものことですが間違いを含む可能性があります。その時は積極的に教えて頂けると助かります。
あくまで私の知識が及ぶ範囲での解説となりますので、ご了承ください。

追伸:今回の記事では、主にVRAM消費量の観点から最適化を行います。純粋な描画負荷の話はまた別の機会に詳しく触れさせて下さい。

挨拶

要求スペックがAAAタイトル並みと言われて久しいVRChatですが、皆様いかがお過ごしでしょうか。
身近な範囲のイベントでGoodアバターが求められたり、VRChat公式がアバターの容量制限を改めたり。
以前から最適化関連の記事は書こうと思っていたのですが、ようやくきっかけが見つかったということで、行動に移すことにしました。
拙くも私の持てる範囲での知識を盛り込んだ記事となっていますので、参考にして頂けますと幸いです。
ではでは早速本編へ~

第一章:前置き

1. 最適化ってそもそも何?

「最適化」「軽量化」などと呼び方にバラツキこそあるものの、この言葉を聞いたことが無い、という方はそう居ないでしょう。
人によってその定義が違ったりもする言葉ですが、私は主に下記3つの行為を包含した言葉だと考えています。

1. ダウンロードサイズの削減
2. 描画負荷の削減
3. パフォーマンスランクの向上

といった感じに分けてはみましたが、とりあえずは「アバターの表示にかかる負荷を減らす行為」だと思って頂ければそれで大丈夫です。

2. 最適化の必要性

「自分視点では重くないし、わざわざやる必要はない」
そう思う方も中にはいらっしゃるかもしれません。
実際のところ、自分自身が不自由していない場合、残念ながら最適化というのは無視されがちな行為になります。
しかしここで意識していただきたいのは
アバターを処理・表示するのは、あくまで各自のPCである」 ということです。
それを踏まえると、アバターを見せるという行為は少し意地悪な言い方をすると
アバターの負荷を相手に押し付ける」行為とも言えてしまうわけでして...

...もうお分かりですね?
とどのつまり、最適化というのは相手への配慮に他ならないのです。
何より「アバターが重すぎてあの人が居るだけで重い」といった事態は、誰も望んでいないはずです(そんなケースはごく稀ですが)

そんなこんなで、最適化の必要性についてご理解いただけましたら、次へ進んでいきましょう。

第二章:基礎知識

1. ダウンロードサイズとは

アバターの最適化を考えるうえで、まず真っ先に取り組むべきと考えられるのがこの項目です。
ダウンロードサイズとは、アップロードしたアバターのデータサイズのことで、この分のデータを相手のPCがダウンロードすることでアバターを表示できる仕組みになっています。

スクリーンショット 2024-05-31 183759.png
参考までに、こちらが私の普段使っているアバターの数値です。

後ほど触れる例外もありますが、一般的にはこの項目はVRAM消費量(テクスチャメモリー)に直結します。
またアバターを表示するのにかかる時間の短縮にもなるため、まずもって削減しない手はないと言えるでしょう。

基本的にこの項目は、衣装や素体、その他オブジェクトなどに使用されるテクスチャ、つまり画像データが大半を占めています。

VRAM使用量については、少し踏み込んだ内容をこっちに書いたので気になる方はどうぞ。

2. 描画の仕組みと負荷について

ダウンロードサイズをひとしきり最適化した後、次にターゲットとなるのが純粋な描画負荷です。
あまり深く解説するとボロが出r(
...まあ私自身の理解が及ばない範囲にもなってくるので、簡単な解説に留めます。

UnityやVRChat上での描画負荷は「Draw Calls」という値を基準に判断することができます。
このDraw Callsというのは、ざっくり言うと「CPUからGPUへの描画命令」のことで、一般的にはこれが少ないほど描画負荷が低いものとみなすことができます。
この描画命令には毎度それなりの時間がかかり、またゲームのフレームはそれらがすべて完了してから表示されるため、この値はFPSに直結すると言えるでしょう。

してこの"Draw Calls"はさらに二つに分けられ、

Batches:メッシュの描画命令
SetPass calls:マテリアルの描画・更新命令

Unity上ではこの二つの項目を別々のものとして確認することになります。

どちらがよりパフォーマンスに影響するのか...については明確な回答が出来ないのですが、まあ両方とも少ないに越したことはないです。

スクリーンショット 2024-05-31 211105.png
参考までにこちらが私のアバター(最適化済)を単体で表示したときの数値です。
Batches:18
SetPass calls:15
ちなみにFPSの項目はハードによって異なるので、他者との比較では全く参考になりません

3. パフォーマンスランクとは

恐らく上記の2つより圧倒的に知っている人が多いはずです。
VRChat公式が定め、アバター最適化のガイドライン的役割も果たしている、アバターの総合的な負荷の目安です。
Excellent, Good, Medium, Poor, VeryPoorと続き、左に行くほど負荷の軽いアバターという評価になります。

大人数が集まるイベントではMediumやGood以上のアバターが求められる場合もあるため、決して無視のできない項目であることはお分かりでしょう。
長らく更新されていないことから実態との相違は否めませんが、それでも今なお最適化の参考にできる基準です。

具体的な基準はこちらからご覧になれますので、興味のある方はどうぞ。

第三章:作業開始

ここまで、アバターの最適化を考えるうえで注目すべき3つのポイントについてお話しましたが、なんとなくご理解いただけましたでしょうか。
正直なところ、こういうのは実際に手を動かす方が手っ取り早いので、そろそろ本題に入っていきましょう。
※作業開始前の数値を記録しておくと、あとからその効果を確認できるのでおすすめです。

0. 必要なパッケージの導入

まずは先に必要なツールを導入してしまいましょう。

①lilAvatarUtils

アバターに使われているテクスチャを一覧表示できるツール
lilToonをVCC経由で導入するとついてくる

②VRWorld Toolkit

シーンのビルド後の容量と、その内訳を確認することができるツール
VCCにデフォルトでついてくる
アップロード時の圧縮がかかった後の数値が表示されるので、VRChat上での正確な容量が知りたい場合はこっちから確認する必要がある

③Avatar Optimizer(AAO)

アバターのルートオブジェクトに"AAO Trace and Optimize"というスクリプトをアタッチするだけで、できる範囲の軽量化を非破壊的に行ってくれる神ツール
手動設定も活用すれば比較的簡単にGoodを目指せるため、是非とも使いこなしたい一品

④anatawa12's gists pack

アバター関連の便利なツールが詰め込まれたパッケージ
これまたVCCにデフォルトでついてくる

以上の導入が済んだら、次へ進みましょう

1. ダウンロードサイズの削減

ダウンロードサイズを削減するうえで、まずはいくつか原則があります。

ダウンロードサイズ削減の原則

  • 1アバターにつき入れるのは1衣装までにすること
  • 使わないオブジェクトは消すかEditorOnlyにすること
  • テクスチャ解像度は2K以下に留めること
  • テクスチャにはすべて圧縮をかけること
  • クランチ圧縮は出来るだけ避けること

以上5点は、容量削減を行う上での鉄則です!
ではそれぞれについて解説していきましょう。

1. 単一のアバターに複数の衣装セットを実装しないこと

ダウンロードサイズがあまりにも大きい場合、まずはこれを疑ってみましょう。
VRChatでは、ExMenuとアニメーションを設定することで衣装や小物の表示を切り替える手法が一般的ですが、このうち衣装セットごと切り替えるような実装は、一般的に強く非推奨とされています
具体的に言うならば、
・衣装セットA
・衣装セットB
・衣装セットC
がアバター配下に存在して、それらをアニメーションで"まとめて"切り替えるような実装の仕方を指します。

この方法がなぜダメなのか
答えは単純で、全ての衣装セット分のデータが1アバターに詰め込まれるからです。
ただでさえ重い衣装を複数放り込んだら...もう分かりますね?
そうです、クソ重アバターの爆誕です。
加えてUnity/VRChatの仕組み上、仮にモデルが非表示であっても、そのテクスチャデータはVRAMを占有します
1度に着れるのは1衣装までなのに、VRAM上は全衣装分の容量が確保されるため、見る人のVRAMをあっという間に窒息させてしまうわけです。

この問題の解決方法は単純で、衣装セットごとにアバターを分けることになります。
このことを指してよく「1アバター1衣装」と言ったりします。

ちなみに「セットごと」切り替えるのが問題なのであって、1衣装内でのパーツ切り替えや、複数の衣装からパーツを持って来ることに関してはさほど問題ではありません。
ただし、パーツの元となる衣装が1枚のテクスチャで構成されている場合は、パーツのサイズ等を加味しつつ解像度を下げる必要が出てきます。
面倒であればとりあえず2Kにしておきましょう。

1アバターにつき、入れる衣装は1セットまで!
複数の衣装セットを使いたい場合は、アバターを分けて対応しましょう。
さもないと見る人のVRAMを窒息させてしまう可能性があります。

1アバター1衣装の原則について、ご理解いただけましたら次へ進みましょう。

2. 使わないオブジェクトは、消すかEditorOnlyにすること

続いて二つ目、余分なデータを削り取る作業に入っていきます。
VRChatのアバターアップロードの仕組みについても軽く触れつつ進めていきましょう。

VRChatのSDKは、

  1. アバターの配下にあるオブジェクトを取得
  2. 依存関係を解析し、そのオブジェクトが要求するファイルやデータをまとめる
  3. それら全てに独自の圧縮をかけ、VRChatのサーバーにアップロード

といった流れを踏んでアバターをアップロードします。
今回注目するのは主に2番目の部分で、ここに余計なデータが含まれないようにするのが目的です。

作業内容はいたってシンプルで、
使われていないオブジェクトに「EditorOnly」タグを付けるだけで完了します。

スクリーンショット 2024-06-01 093721.png

このEditorOnlyタグというのは、文字通りエディタ、つまりUnity上でだけ表示される、という意味になります。
このタグを付けることで、そのオブジェクトが使用するメッシュやマテリアル、テクスチャなどのデータがビルド時に除外され、結果余分なデータがアバターに含まれる、といったことが無くなります。
ただし必要なものに誤って付けてしまうと、VRChat上で不具合の原因になるので気を付けましょう。

不要なオブジェクトは「EditorOnly」タグをつけてビルド対象から除外する!
そのオブジェクトに付随するデータがアップロードに含まれなくなります。
必要なオブジェクトに誤って付けないように注意!

3. テクスチャ解像度は2K以下に留めること

3つ目にして最重要ポイント、おそらくこれが最も効果的な容量削減の手段になります。
これもまた、画像のデータサイズと解像度の関係について、先に少しだけお話ししてしまいましょう。

Unity上で指定できる画像の解像度のうち、以下の解像度をそれぞれ

・1024x1024:1K
・2048x2048:2K
・4096x4096:4K
・8192x8192:8K

と呼びます。
一般的にアバターのテクスチャに使用されるのは、おおよそ1K ~ 4Kの範囲です。

画像のデータサイズは基本的に画像の解像度に依存し、1辺の解像度が2倍になると、データサイズは4倍になります。
4K画像と1K画像では、実に16倍もの容量差が生じるわけです。

加えてUnityで利用可能な圧縮形式では、アルファチャンネル、つまり透明度を含む画像は、含まない画像に比べて、これまた約2倍の容量を持つことになります。
これには凹凸表現に役立つ「ノーマルマップ」や、表情のうち赤面などを含むテクスチャが該当します。

では以上のことを軽く頭に入れたうえで、作業に移っていきましょう。

まずは現在のテクスチャ内訳を確認します。
Unityのエディタ画面から、画面上部の"Window ⇒ _lil ⇒ Avatar Utils"と進んでください。

スクリーンショット 2024-06-01 100123.png

以下のような画面になったら、左の"Hierarchy"タブから、アバターのルートオブジェクトをドラッグします。

スクリーンショット 2024-06-01 100354.png

するとこういった画面になります。

スクリーンショット 2024-06-01 100820.png

ここで主に注目すべき項目は

  • Max Resolution:Unity上で設定するテクスチャ解像度
  • VRAM Size:予想されるVRAM使用量の概算値

の主に二つになります。
ここで変更前のVRAM Sizeを記録しておくといいかもしれません。

まず"Max Resolution"の項目に、一つでも4096x4096と表示されている画像があれば、それらは全て2048x2048に落としてしまいましょう。
実のところ2Kと4Kの違いを体感することはそう無く、近距離で見ていても言われない限り気づかない場合がほとんどです。
また"VRAM Size"は基本的に解像度に大きく影響されるため、テクスチャの解像度を落とせば、自ずとVRAM使用量も減る仕組みになっています。
余裕のある方は、あまり目立たない細部のテクスチャ解像度を1Kに落とすなどしてみてもいいかもしれません。

Unity上の数値を参考にすると、同じテクスチャの"Max Resolution"を変更した場合のVRAM使用量は、
4K:10.7MB
2K:2.7MB
1K:0.7MB
といった風な差がつき、同じことを透明度情報を持つノーマルマップでも行うと
4K:21.3MB
2K:5.3MB
1K:1.3MB
といった様により顕著な差が出ます。
解像度を下げることがいかにVRAM使用量に影響を及ぼすか、これだけでも見て取れるのではないでしょうか。

ひとしきり解像度の変更を終えたら、忘れずに左上の"Apply"ボタンを押しましょう
これによりlilAvatarUtils上で設定した数値が、Unityのインポート設定に反映されます。

最後にウィンドウ右上のリロードボタンを押して、VRAM Sizeを再計算しておきましょう。
元の4Kテクスチャの数が多ければ、この部分がゴッソリ削れているはずです。

テクスチャのMax Resolution"は2Kまでに留めること!
普段から4K以上のテクスチャを身にまとっていても、その恩恵を感じる機会は少ないかと思われます。
近くでも荒さを感じず、かつ容量を抑えたいのであれば、とりあえず2Kに設定しておくといいでしょう。

4. テクスチャには必ず圧縮をかけること

先ほど最重要ポイントを出したばかりですが、これも先ほどと同じくらい重要なポイントになります。

ここで言う「圧縮」とは、Unity側が用意している「GPUでデータを扱うための圧縮形式」のことで、これを設定するか否かで容量が大きく変化します。

Windowsプラットフォームであれば
RGB Compressed DXT1|BC1
RGBA Compressed DXT5|BC3

Androidプラットフォームであれば
RGB(A) Compressed ASTC 6x6 block

などが代表的な圧縮形式として挙げられますが、この形式名については覚える必要が無いので一旦忘れてください。

上に書いたこの形式は、Unity側の画像圧縮設定を"Normal Quality"にした時に使われる形式で、デフォルトではこれらが使われるようになっています。
ですが、稀に圧縮設定が"None"、つまりテクスチャを全く圧縮していない状態で配布されている衣装やアセットが存在します。
何か特別な事情が存在する可能性もあるのですが、基本的に圧縮前後で目立ってクオリティが落ちる、ということはあまりありません。
今から解説する方法で圧縮形式を設定しておきましょう。

1. 非圧縮のテクスチャを見つける

先ほども登場した"lilAvatarUtils"を使います。
先ほどと同じステップを踏むとアバターのテクスチャ一覧が表示されると思いますが、その中に、同じ解像度のテクスチャと比較してVRAM Sizeが大きいテクスチャがあれば要チェックです。

※この画像では解説のためにわざと圧縮を解除しています
image.png

ということで2Kのテクスチャを1個だけ圧縮解除してみたところ、他が2.7MB、透過を含む画像でも5.3MBのところ16MBまで膨れ上がりました。
元の画像は不透過ですので、2.7MBと16MBで実に約6倍もの容量差が生じています。

左の名前の部分をダブルクリックすると元データに飛べるので、そこから圧縮設定をしに行きましょう。

スクリーンショット 2024-06-06 190929.png
元データに飛ぶと、画面右の"Inspector"タブがこんな表示になります。
ここは画像データのインポート設定と呼ばれ、解像度や圧縮形式、ミップマップの有無などを設定することができます。
今回使うのはこのうち画面下の赤枠の部分です。

一番下の"Compression"の項目が"None"になっているので、その部分をクリックして"Normal Quality"に変更しましょう。
※最初から"Normal Quality"になっていれば問題ありません。
スクリーンショット 2024-06-06 192113.png
設定後、右下の"Apply"を押すことで、設定が反映されます。

では確認のため、lilAvatarUtilsの画面をもう一度見てみましょう。
左上のリロードボタンを押して最新の状態にしてから確認してください。
スクリーンショット 2024-06-06 192500.png
他のテクスチャと同じくらいの容量になっていれば、作業は成功です。

ちなみに圧縮をかけない場合、高解像度になるほど影響が甚大になっていきます
image.png
はい、4K以降が悲惨なことになってますね。

テクスチャには必ず圧縮をかけること!
圧縮による微細な劣化を気にするよりも、容量増加の方がずっと深刻です。
そもそもデフォルトは"Normal Quality"ですので、非圧縮のテクスチャが一つでもあれば遠慮なく設定してしまいましょう。

5. クランチ圧縮は出来るだけ避けること

最後四つ目ですが、これに関しては疑問に思った方もいらっしゃるのではないでしょうか。
その疑問にお答えするためにも、まずはクランチ圧縮について解説してしまいましょう。

クランチ圧縮とは、超ざっくり言うと「品質を犠牲に画像データサイズを下げる」圧縮方法で、通常の圧縮形式に比べてさらに強い圧縮をかける手法になります。
圧縮に長い時間がかかる一方で、展開は高速であるという特性を持っており、ワールドのテクスチャなどには有効な圧縮形式となります。

...と、ここまで聞くと超便利な圧縮手段であるかのように聞こえますが、もちろんデメリットもあります。

1. 品質劣化

圧縮してるので当然と言えば当然ですが、通常の圧縮よりその劣化度合いは進行します
解像度を既に2K以下に落としているなら、容量的にも必要性は低いでしょう。

2. ランタイムの展開負荷

先ほど「展開は高速である」と言いましたが、結局のところ展開処理が走るのに変わりはありません
加えてアバターはワールドと違い、その人がJoinしたタイミングで展開を行うことになるため、FPSの不安定化を招きかねません。

3. VRAM使用量に影響しない

一番最後にして一番大事なポイントです。
ダウンロードサイズがモリモリ減るので、さもアバターの負荷が軽くなったように感じてしまうのですが、実のところクランチ圧縮をかけてもアバターのVRAM使用量は一切減りません
これはクランチ圧縮の「展開するとデータサイズが元に戻る」性質に起因しており、サイズの大きい画像にクランチ圧縮をかけたとしても、結局展開時にはその容量に戻ってしまうためです。

といった感じで、一般的にクランチ圧縮は非推奨な方法となっています。
そもそもここまで上げた3つの方法を踏めば、ダウンロードサイズは既にかなり減っているはずなので、文字通り最終手段と言っていいでしょう。

クランチ圧縮による容量削減は避けること!
確かに容量は減りますが、それ相応に無視できないデメリットもあります。
加えてVRAM使用量には影響を及ぼさないので、そこを勘違いしないよう注意しましょう。


以上が代表的なダウンロードサイズの削減手段です。
成果が気になるようであれば、一度テストアップロードを行い、VRChat上、あるいはVRWorld Toolkitにてダウンロードサイズを確認してみるといいでしょう

TIPS:VRWorld Toolkitの使い方

スクリーンショット 2024-06-01 121838.png

スクリーンショット 2024-06-01 121940.png

赤線で示した"Build Size"という項目がアバターのダウンロードサイズになります。
右赤枠の"Build Report"では、ダウンロードサイズのうち何がどれだけの割合を占めているのか確認することができます。
ただしここに表示されている容量はVRChatSDKによる圧縮がかかる前のものなので、常に正しいとは限りません。

2. 描画負荷の削減

まずはアバターダイエットに成功したということで、次はより踏み込んだ最適化に触れていきます。
具体的な方針としては、上の方で軽く触れた"Draw Calls"を基準に、その数を減らす方針で進めていきます。

0.現状確認

作業開始の前に、まずは現時点での数値を確認しておきましょう。
画像の通り、再生ボタンを押してから、画面右上の"Stats"をクリックすると、描画関連の情報が表示されます。
※測定環境を揃えるため、予めリアルタイムライトの影をオフにしてください。

スクリーンショット 2024-06-01 144052.png

スクリーンショット 2024-06-01 140455.png

主に見るべきは、先ほども触れた

  • Batches
  • SetPass calls

以上二つになります。
このアバターでは、現時点でそれぞれ30と14であることが見て取れますね。

参考までに、私のホームワールドの全体を映したときの数値がこんな感じです。
まずもってそんなことは無いと信じたいですが、現状の数値がどちらか一つでもこれより大きいのであれば、危機感を持った方が良いです。
スクリーンショット 2024-06-01 135234.png

1. ドローコールを減らすには?

では具体的にどうすればそれらを減らすことができるのか。
この数値に直接影響を与えるコンポーネントを列挙して行こうと思います。

1. Skinned Mesh Renderer / Mesh Renderer

image.png

これは主に"Batches"に影響を与えるコンポーネントです。
Batchesはメッシュの描画指示ですので、メッシュが多ければそれだけその数は増えます。
なおかつアバターや服に使われる"Skinned Mesh Renderer"は、通常の"Mesh Renderer"と比較して負荷が高いです。

メッシュを結合することでBatchesを効果的に減らすことができますが、表示・非表示の切り替えも結合後のメッシュが最小単位となるため、結合するメッシュの選定は慎重に行う必要があります。

2. Material

image.png

これは主に"SetPass calls"の方に影響を与えるコンポーネントです。
メッシュの質感やテクスチャ情報を持ったコンポーネントで、オブジェクトの色を変えたりテクスチャを入れ替えたりするときに出てきます。

これもメッシュ同様、結合を行うことで総数を減らすことができます。
同じ内容のマテリアルが複数ある場合、どれか一つに統一してしまうのも効果的ですね。

3. Realtime Light

最後にしてラスボスの登場です。
一般的にアバターに同梱されたライトは「アバターライト」と呼ばれますが、このコンポーネントは"Batches"と"SetPass calls"の両方に大きな影響を及ぼします

これに関しては実測値を見て頂いた方が早いでしょう。


1. ワールドライトのみ(デフォルト)

スクリーンショット 2024-06-01 144927.png
Batches:30
SetPass calls:14


2. アバターライト1個(Spot/Point, 影の有無関係なし)

スクリーンショット 2024-06-01 144821.png
Batches:57
SetPass calls:41
(計測ミスってるかも?)


3. アバターライト1個(Directional, 影なし)

スクリーンショット 2024-06-01 144821.png
Batches:57
SetPass calls:41


4. アバターライト1個(Directional, 影あり)

スクリーンショット 2024-06-01 145622.png
Batches:99
SetPass calls:56


見て頂くと分かる通り、アバターライトを入れたことによって両者の数値が跳ね上がっているのが見て取れると思います。
VRC公式も言及していますが、これはライトが触れる全ての物が2倍のドローコールでレンダリングされるためです。
...3倍以上に跳ね上がってるものもありますが、とりあえずそういう物なんです、はい。
元の2倍になる、ということは元が重ければ大変なことになるわけで...

最近だと某影システムなんかが代表例になりますが、それに限らずとも恒常的にアバターライトを使用するギミックは、"普段使いは"避けた方が良いでしょう。

VRChat公式では以下のように言及されています(和訳済み)

常に点灯しているライトは使用しないでください。アニメーションのオーバーライド(Animation Override)を使用して懐中電灯のオン/オフを切り替えるか、ライトをまったく使用しないでください。

Material、Skinned Mesh Renderer, アバターライトは、描画負荷に直接響く!
値として実測できる範囲では、以上三つが主要な削減対象になると考えています。
実際のところもっと多様な要素が影響を及ぼすのは間違いありませんが、まずはこの辺りを減らしておけば間違いはないでしょう。

2. 描画負荷(ドローコール)を減らす

ではここからは、実際に上に挙げたコンポーネントを減らしていく作業になります。
やれメッシュだ結合だと難しい言葉を使った気がしますが、実際の内容としてはツールを使うだけです。

それが皆様ご存じAvatar Optimizerです。
先日のアップデートにてSkinned Mesh Rendererの自動結合に対応し、その総数を減らすことが格段に簡単になりました。
加えて手動での結合を行えば更なる削減も可能で、これを駆使すればGoodのアバターも夢ではなくなります。

駄弁ってても仕方ないのでそろそろ手を動かしましょう。

1. アバターに"AAO Trace And Optimize"をアタッチする

アバターのルートオブジェクトを選択し、Inspectorタブの一番下に行くと、"Add Component"というボタンがあるはずです。
スクリーンショット 2024-06-01 160821.png

これをクリックしたのち、検索欄に「AAO」と入力することで、Avatar Optimizerの各コンポーネントが出てきます。
その中から「AAO Trace And Optimize」を選択し、アバターにアタッチしましょう。

スクリーンショット 2024-06-01 161030.png

これで自動軽量化は終わりです。
このスクリプトをアタッチすることで、あとはビルド時に勝手に軽量化が走ります

2. ActualPerformanceWindowを有効化する

効果を分かりやすくするため、パフォーマンスランク計算ツールを有効化します。
Tools->anatawa12's gists selector と進み、"ActualPerformanceWindow"にチェックを入れましょう。
スクリーンショット 2024-06-01 162012.png
スクリーンショット 2024-06-01 162135.png

3. 効果確認

では再生ボタンを押してプレイモードに入ります。

image.png
Statsタブを見ると、

  • Batches:30⇒23(-7)
  • SetPass calls:14⇒14(±0)

という結果になりました。

続いて先ほど有効にした"ActualPerformanceWindow"の方に目を向けると、

適用前
スクリーンショット 2024-06-01 162945.png

適用後
スクリーンショット 2024-06-01 162955.png

マテリアル、Skinned Mesh Rndererともに4つ減少し、アバターランクがPoorまで上がっているのが確認できるかと思います。

ちなみにアバターライトは自動削除の対象とならないため、自分で消す必要があります。

正直なところ、描画負荷の低減と言っても、既にほかの最適化を済ませたうえでここに居るので、これ以上あまりやることはありません。
もしメッシュの手動結合(AAO Merge Skinned Meshなど、さらなる最適化を求める場合はこちらの記事を参考にすると良いでしょう。

一応手動結合を突き詰めると、見た目を全く損なわずにここまで軽量化できます。
スクリーンショット 2024-06-01 164500.png
スクリーンショット 2024-06-01 164454.png
スクリーンショット 2024-06-01 164443.png

服の脱ぎ着などはオミットすることになりますが、元から大した頻度でしないので問題ありません。
Physboneだけ別のツールで削ってるので、そこだけご了承を!

困ったらとりあえず「AAO Trace And Optimize」を付けよう!
AAOには軽量化に役立つありとあらゆる機能が入っている、と言っても過言ではないので、是非とも積極的に活用していきましょう。

3. パフォーマンスランクの向上

では最後のステップ、パフォーマンスランクの向上です。
今までのステップを全て踏んできているのであれば、基本的にこの先の作業は不要でしょう。
ここから先はGoodやMediumのアバターを条件とするイベントに行かれる方、あるいはその境地を目指したい方向けです。

これに関しては削減に関する共通のアドバイスが存在しないため、足枷になりやすい項目とその対処法について書いていこうかと思います。

まずはざっと表を出してみましょう。
各項目の数値がそのランクの上限値で、それを超えると1個下のパフォーマンスランクに落とされます。

Excellent Good Medium Poor
Triangles 32000 70000 70000 70000
Texture Memory 40MB 75MB 110MB 150MB
Skinned Meshes 1 2 8 16
Material Slots 4 8 16 32
Physbone Components 4 8 16 32

1. Triangles

「ポリゴン数」と言った方が馴染み深いかもしれません。
モデルに含まれる三角面の数のことで、影響はそこまで大きくないものの、基本的にこの数が小さいほど低負荷なものと見なすことができます。
手の込んだ衣装やアバターを使っていると簡単に超えてしまう印象ですが、Avatar Optimizerのコンポーネントを使うことである程度は削減できます。
AAO Rmove Mesh By Blendshape
 貫通防止用シェイプキーが設定されている部分のメッシュを削除できる

AAO Remove Mesh in Box
 Unity上で指定した範囲のメッシュを消すことができる

公式マニュアルになりますが、この辺りを参考にすると良いでしょう。

2. Texture Memory

端的に言ってしまえばVRAM使用量です。
この記事でお話ししたステップを踏んでいればまずVeryPoorにはならないと思います。
対処法としては
テクスチャの解像度を下げる
参照する画像データを減らす
適切に圧縮を設定する

などが挙げられると思います。

3. Skinned Meshes / Material Slots

Skinned Meshes:衣装や素体など、アーマチュアに追従して動くメッシュの数
Material Slots:質感およびテクスチャ情報の数
衣装やアクセサリーをたくさん入れると、その分だけこの項目が増えます。
対象法としては
AAO Trace And Optimize
 元のアニメーションを参照しつつ、見た目に変化がないように自動で結合する
AAO Merge Skinned Mesh
 マテリアルなどを参照しつつ、可能な限りそれらを1つにまとめる。
 アニメーションによる切り替えなどは考慮されない。

などが挙げられます。
さっきも出てきましたね。

4. Physbone Components

アバターに設定されたPhysboneの総数です。

AAOにもPhysboneを統合するツールはありますが、純粋に数を減らすのであれば、VRCQuestToolsRemove Physbonesという機能を使うのがおすすめです。

本来の用途であるQuest対応についてはこちらの記事をご参照ください。


制限をオーバーしやすい(と感じる)項目については以上の通りとなります。
ありがたいことに、パフォーマンスランク関連では結構多くの記事が出回っていますので、もしこれ以外でオーバーする項目がある場合は、個別に調べて頂くのが手っ取り早いかと思われます。

パフォーマンスランクに関しては共通のアドバイスがしづらいです
AAOやその他パッケージの機能を活用するほか、必要に応じて先人の方々の記事を参考にするとよいかと思います。

第四章:私が今のVRChatに思うこと

そろそろまとめに入りたい頃合いですが、もう少しだけお付き合いください。

冒頭で「要求スペックがAAAタイトル並み」とふざけ半分に言いましたが、この点に関しては「おふざけ」で終わらせるべきではないと私は思っています。
やれ「VRAMは16GB欲しい」だとか、「世間のミドルレンジはローエンド」だとか
VRでのゲームプレイに、通常より高い処理能力が要求されるのは事実です。
しかしそれを踏まえても、今のVRChatの環境は異常であると私は考えます。

実のところ、VRChatがSteam上に掲示している推奨GPUは、"Geforce GTX 970"です。
推奨スペックが長年更新されていないことも一因ではありますが、現在が当初の想定から逸脱した環境であるのもまた事実です。
ではどうしてこんな環境になってしまったのか。
他のプレイヤーを悪く言うつもりはなく、かつこれは私自身への戒めでもありますが、ひとえに「最適化不足」と言わざるを得ないのが現状です。
稀に「VRChatは重い・最適化不足」との言葉を耳にしますが...

違います

重いのは我々プレイヤーのアバター、そしてワールドです

ここで思い出して頂きたいのは、VRChat公式の掲げるスローガンです。

Create, Share, Play

我々プレイヤーは、プレイヤーであるとともにクリエイターでもあるのです。
何かを売っていなくても、世に出していなくても
自分好みの姿にカスタマイズしたアバターは、各々の立派な創作物です。

だからこそ!
そのアバターを気兼ねなく、最高の状態で使うためにも!
クリエイターとして、是非とも最適化に目を向けて頂きたい、と思うのです。

ここで大事なのは「目を向けること」であって、パフォーマンスランクやこの記事で触れた基準などではありません
たとえほかの人よりアバターが重くとも、最適化の意識を持つことがまず重要なのです。

そうしてプレイヤーに最適化意識が浸透し、いつしかそれが当たり前の行為になる。
勝手ながら、私はそんな理想をこの記事に込めています。

第五章:まとめ

今回の記事を通じて、私が皆様に伝えたかったことは

  • ダウンロードサイズの減らし方
  • 描画の仕組みと負荷の低減
  • パフォーマンスランクとの付き合い方

そして

  • プレイヤー各々が最適化意識を持つようになって欲しい

ということです。
無理にやれとは決して言いません。
気が向いたときに少しでも取り組んでいただければ、それで充分です。

では長くなりましたが、今回はここまでです。
追加の情報や間違っている部分の修正など、今後も更新する可能性はあるので、その時はまたよろしくお願いします。
では皆様、よいVRChatライフを!

おまけ

今回参考資料として使ったアバターは、CRIM SODA氏作の「Lemone」ちゃんです。
かわいい

image.png
image.png

17
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?