Unity
Blender
VRChat

VRChatアバター最適化のTips [日本語訳]

VRChatの公式ドキュメントに掲載されているアバター最適化のTips(Avatar Optimization Tips)を日本語訳しました。
内容は以前から随所で語られていたものですが、一つの記事にコンパクトにまとめられているので、これからアバターを改変/自作する人が一読することで概要をつかみやすくなると思います。

筆者の英語力がヘチョヘチョなため、おかしな箇所を見つけたらコメントかTwitterで連絡いただければ幸いです。
基本文字装飾などは原文ままです。

以下本文

アバター最適化のTips (Avatar Optimization Tips)

軽量でみんなのfpsを節約できるような愛されるアバターを作りたいかい?このtipsに従って改善しよう!

ここで推奨される数字や制限はいつでも変更される可能性があります。以下の記述の一部は技術的な意味では正確ではありませんが、このドキュメントはアバターの最適化方法を学ぶ新米ユーザーをサポートするために書かれています。

Cats Blender Plugin(MITライセンス)のようなコミュニティ発のツールを使えば、とても簡単にモデルを最適化でき、VRChatアバターのよくある問題を解決してくれます。こういったツールを使うことを強く推奨します。タスクがラクになり、みんなのパフォーマンスが改善します。

ダイナミックボーンとクロスの制限(Limit usage of Dynamic Bone and Cloth)

ダイナミックボーンはUnityのasset storeで購入できるスクリプトで、これを使えばアバターのボーンを指定して、揺れるような動きを表現することができます。また、重力のような静的な荷重を設定でき、髪をよりリアルに垂らすことも可能です。

ダイナミックボーンはプロセッサで動作するため、CPUの計算時間をかなり消費します。また、これはアバターに追加できる中で、おそらくもっとも計算コストを大きくする要因です。VRChatでは、30個以上のボーンに適用しないことを強く推奨します。

ここで「適用したボーン」とは、ダイナミックボーンでrootに指定したボーン以下にあるすべてのボーンのことです。ただし、例外としてリストに載せたボーンとその子供は省きます。もしスカートにダイナミックボーンを追加して、3個のボーンからなる骨組みが16組あるとすれば、ダイナミックボーンを適用したボーンは3x16=48個となります。これでは多すぎます。

繰り返しますが、VRChatではまず30以下のボーンにダイナミックボーンを適用することを推奨します。

付け加えて、ダイナミックボーンのコライダーは、必要な計算量をざっくり2倍にします。これは、スカートに48個の揺れるボーンをつけ、両手にコライダーをつけた場合、144個の揺れるボーンがあることに相当します。(各コライダーが48個のボーンに相当するため、3倍になる。)そのため、ダイナミッックボーンのコライダーをいれないことを推奨しますが、どうしてもいれる場合は多くとも1つか2つまでにしてください。

クロスはデフォルトのUnityコンポーネントですが、ダイナミックボーンと同等の描画コストがかかるうえ、設定がさらに難しいです。クロスを使うことは大幅に制限し、200点以上の頂点を持つメッシュには使用しないでください。

ダイナミックボーンを使う場合は、下記ビデオ(英語)を参照し、適用するボーンの数を減らす方法を確認しましょう。
IMAGE ALT TEXT HERE

メッシュ数の削減(Reduce the amount of meshes on your avatar)

アバターが持つメッシュには2種類あります。静的メッシュレンダラー(Static Mesh Renderer)と、スキンドメッシュメッシュレンダラー(Skinned Mesh Renderer)です。静的メッシュは変形しませんが、スキンドメッシュは各ボーンの位置に基づき変形します。このスキンドメッシュはとても計算コストがかかるので、アバターには1つだけ適用するのが良いです。それ以上のスキンドメッシュを持つべき理由はほぼありません。ほとんどの場合、追加のアイテムをオリジナルの3Dモデルに組み込むことができます。(←訳微妙)

それに加えて、アバターに追加された各メッシュがdraw callsを追加します。本来これは、画面に何かを描画するとき、プロセッサーがグラフィックカードに指令を送る際に消費する時間のことです。

そのため、VRChatでは最大でもスキンドメッシュレンダラーは1つまで、静的メッシュレンダラーは3つまでを推奨しています。Blenderでメッシュを結合するのはとても簡単なので、以下のビデオを参照してください。

特に、Cats Blender Pluginを使っている場合、Fix Modelを使えば自動的にメッシュを結合することができます。もし、メッシュの間引きや編集性のために、Catsを使ってMaterialやLoose Partsでメッシュを分割している場合、もう一度メッシュ結合することを忘れないでください。
IMAGE ALT TEXT HERE

マテリアル数の削減(Reduce the amount of materials you use)

各マテリアルもまたdraw callsを追加するため、より多くのプロセッサーを消耗します。例えば10個以上のマテリアルを持っている場合、テクスチャの統合を検討してください。コミュニティのツールでは、統合はとても簡単にできます。詳細はマテリアル最適化の動画(英語)を参照してください。
IMAGE ALT TEXT HERE

描画コストの高いシェーダーを使わない(Avoid expensive shaders)

一部のシェーダーはGPUのレンダリングにとても時間をかけます。Unityのstandard shaderか下記のコミュニティ発のシェーダーを検討してみてください。

さらに技術的なことを言うと、過剰なshader passを持つシェーダーはdraw callsを増やすため使うべきではありません。ただし、これはほとんどのユーザーにとってあまり関係なく、コミュニティでよく使われるシェーダーであれば十分です。

また、過剰なshader keywordsを使うシェーダーは使うべきではありません。使うと、VRChatのレンダリングに重大かつ予期しない問題を招く可能性があり、アウトプットログが不要なエラーメッセージで埋め尽くされます。シェーダーに過剰なshader keywordsを入れる必要はないので、狙いの表現に必要なものだけ選択し使ってください。(Shader keywordsが何かわからないまま訳したので間違っているかもしれません)

アルファ透過もまたシェーダーの描画コストを上げる一因です。一般的にcutoutやopaqueモードを使うことを推奨します。透過はかなり描画コストが高くなる可能性があるので、自分が何をしているか理解しているときだけ使ってください!

draw callsが何回呼び出されているか判断するには、Unity profilerが有効です。ただし、平面のフィールド(たぶん床のplaneオブジェクトのこと?)に対するDirectional lightのshadowをオフにしておいてください。

ボーン数の削減(Reduce the amount of bones)

スカーフ、スカート、髪にたくさんのボーンが配置されているだけでも、GPUのskinning calls処理の計算コストが増える可能性があります。使わないボーンがあれば削除して、そのウェイトを親のボーンにマージすることを検討してください。ウェイトのマージ方法は、先述したダイナミックボーン最適化のビデオを参照してください。

パーティクルとその出力数の削減(Reduce the emission amount/amount of particle systems)

パーティクルシステムはクールな表現ができる一方で、とてつもないパーティクル数を処理しきれないPCもあります。使用するパーティクルシステム自体の数と、そこから一度に出すパーティクルの最大値を制限してください。

パフォーマンスを維持したままたくさんのパーティクルを出す方法もあります。これに興味がある人は、dynamic batching for sprite particlesを調べる、コリジョンを使わない、パーティクルの動きを単純化する、などを試してください。

もっと技術的なことを考えているのであれば、パーティクルがどれくらいCPUの計算時間を消費しているかをUnity Profiler viewで確認してください。一般的には、大きな透明のパーティクルは、たくさんの小さな不透明のパーティクルよりも重いです。実はUnityのパーティクルシステムはうまく使えばかなり最適化できて軽量に動作します。

ライトの数を制限する(Limit the number of Lights your avatar uses)

アバターにつけるライトはリアルタイム処理になるので描画コストがとても高くなります。これは、そのライトの光が届くものはすべて2倍のdraw callsでレンダリングされることを意味します。ライトをさらに追加するとより重くなります。これはゲームのパフォーマンスに明らかな悪影響を与えます。常にオンなっているライトをアバターにつけないでください。ライトのオン/オフを制御できるアニメーションオーバーライドを使ってみるか、一切ライトは使わないでください。

もしライトをどうしても使いたいなら、shadowをオフにしてください。リアルタイムのshadow描画はめちゃんこ計算コストがかかるうえ、動くもの対してはそれほど綺麗に見えません。

パーティクルシステムでは、各パーティクルに対してライトを設定することができますが、絶対に実行しないでください!各パーティクルのライトはリアルタイムライトとしてカウントされるため、(もう一回いうけど)とんでもなく描画コストが上がります。

総じて、VRChatのアバターにはいかなる種類のライトでも使うことを推奨しません。あなた自身のアバターに影響があるだけではなく、ライトが当たった他のアバターのパフォーマンスも低下します。

パブリックアバターワールドのガイドライン(Public Avatar World Guidelines)

パブリック申請されたアバターワールドは次のガイドラインに従う必要があります。

項目 最大 理想
スキンドメッシュレンダラー 3 1
マテリアル  10 1~2
ダイナミックボーンの適用ボーン数 50 0~30
ダイナミックボーンのコライダー 2 0

アバター情報(avatar stat)を見る簡単な方法は、Pumkin's Avatar Tools (MIT)というスクリプトをUnityで使うことです。他の情報も含め、このスクリプトでアバターの統計情報(ボーン数など)を見ることができます。これはbeta版のためバグがあるかもしれません。そのときはGitHubにレポートを投げてください。
VRChat SDKに同様の機能を追加することを検討しています。

('19.1.5時点ですでにSDKに実装されていますね。)

推奨するソフトウェアとプラグイン

下記のソフトウェアはVRChatが作成したものではありません。各プロダクトのライセンスを読み、守った上で使用してください。

Unity 2017.4.15f1
Blender
Cats Blender Plugin
Shotariya's Material Combiner
Pumkin's Avatar Tools

以上