VRChatのワールドを軽量化する方法

Unity

単純に「軽量化する」といっても軽量の意味には二つあります。

今回はこの軽量化の二つについて軽く触れ、覚書として残しておきます。

正直自分も手探りでなんやかんやしているだけなので、効率の悪いこととかやっても意味がないこととか、そもそもやってはいけないこととか推奨されない手順を踏んでいる可能性もあります。鵜呑みにはしないでください。

またこの記事の後半は解説記事ですが、前半は解説記事ではなく「この解説を読むといいよ!」という内容になってます。

スポンサーリンク

ワールドの処理を軽くする

ワールドに実際に入ってみて「なにここ重い! 動けないんだけど!」みたいな状況にしないための軽量化です。PCが低スペックな人でも気軽に来れるワールドにしたい場合に必要な軽量化になります。

メッシュをベイクする

Unityで制作された3Dコンテンツには「ドローコール」という概念があります。

これは1フレームで何回CPUからGPUへ描画命令を送っているかを示す値です。ドローコールが増えると処理の回数が増えてFPSが低下、動作がもっさりとしてきます。
つまり軽くするには、ドローコールを減らせばいいわけです。

たとえばお家ワールドに家具を一個一個並べていって、最終的に30個の家具を設置したとします。するとドローコールは最低でも30回となり、1フレーム進むごとに30回の指示がCPUからGPUへと送られて処理されます。
しかしメッシュベイクをすることで、一個一個並べた家具を「一つの物体」として固めることができます。

メッシュベイクを済ませた状態。
これは一つのオブジェクトですが、まるで家具を詰めたフォルダを選択しているかのようにすべての家具が選択状態になっています。

こうすることでドローコールを減らし、実際にワールドにいる際の軽量化、つまりFPSの向上が臨めます。

ちなみにベイクとは「焼く」という意味です。人によっては「メッシュを焼く」という表現をする人もいます。

メッシュベイクをおこなうメリットは上記のとおりですが、デメリットもあります。
メッシュをベイクしてしまうと「一つの物体」として認識されるため、「やっぱりテーブルはもう少し右に移動しよう」ということがあとからできません。

なので基本的にメッシュベイクはほぼ完全にワールドの形が決まってからするといいと思います。

メッシュベイクについては以下の記事のほうが詳しいのでここでは説明しません。

ライトをベイクする

ライトの種類には三種類あります。

ライトの種類はModeから選択できます。
  • 1フレームごとに毎回光の当たり方を計算するRealtime
  • あらかじめ光の当たり方 や影を計算しておいてテクスチャに焼き込むBaked
  • RealtimeとBakedの混合ライトであるMixid

ここではMixidライト以外の二つについて説明します。

Realtimeはその名の通り1フレームごとにライトの当たり方や影をCPUが計算し、その描画処理をGPUに指示します。
先ほどあげた「ドローコール」と同様で、CPUからの指示が多ければ多いほど負荷がかかり、FPSが低下してしまいます。要するにRealtimeライトは重いのです。

そこでワールドに実際にいるときにライトの処理を重くしない手段の一つとして、Unity上であらかじめ光の当たり方や影の計算をして、あたかも光が当たっているかのようにテクスチャに描きこんでおくBakedライトを使う方法があります。

ちなみにこちらもメッシュ同様「ライトを焼く」と表現する人もいます。

ライトのベイクに関しては以下の記事が簡潔でわかりやすいです。

また、ライトのベイクには小さいワールドでも5分、大きいワールドだと1時間とか2時間くらいはかかってしまいます。
ライトのベイク時間を短縮するには以下の記事が参考になります。

メッシュベイクしたものをライトベイクしたらなんかおかしい

なんかメッシュベイクしてからライトのベイクをしたらおかしくなりました。 また同じ現象に遭遇したときに自分で解決できるように書き残しておこうと思います。

Pandoraワールド製作者のMinaさんの助言でなんとか解決。

忘れないようにメモしておきます。

メッシュベイク時に以下の手順を踏みます。

GameObjectからTextureBaker (0)を生成後、いつもどおり進めていきます。
Bake Materials Into Combined Materialをクリックするところまで進めます。
その後、Light Mapping UVs を Generate new UV2 layout に設定してからBakeします。

すると焼け焦げる現象を回避できるようです。

オクルージョンカリングの設定をする

オクルージョンカリングの設定をおこなうと、「視界にオブジェクトが入らないと描画されない」という状態になります。

これもドローコールの削減になり、無駄な処理がなくなるので、その分処理が軽くなります。

オクルージョンカリングをおこなった状態。
視界に入っていない壁が表示されていません。

以下の記事で詳しく説明されているため、ここでは説明しません。

ちなみにこのお家ワールドの家具群はまとめてメッシュベイクしています。そのため、オクルージョンカリングの設定をしていても家具が一つでも視界に入るとすべての家具が描画されてしまいます。

今回はワールドが「一つの部屋」という小さなサイズ感であることと、メッシュベイクでドローコール自体は減っているので大きな問題にはなりませんが、「街」などの広いマップをメッシュベイクする際はオクルージョンカリングを意識して区画で分けてメッシュベイクしたほうがいいです。

ワールドの容量を軽くする

ワールドの容量を減らす、要するにロード時間を短くすることに繋がります。

FBXファイルの圧縮設定を変更する

アセットフォルダ内に存在しているFBXファイルのInspectorから「Mesh Compression」の値を変更します。初期値はOffで、LowよりもMedium、MediumよりもHighのほうが圧縮率が高く容量を小さくできます。

僕はMediumまで圧縮していますが、Offに比べるとLowでも十分圧縮されている気がするのでLowでもいいかと思います。

以下の記事を見た感じ、Mediumまで圧縮する価値も薄そうです。

テクスチャの圧縮をする

テクスチャ圧縮といっても画像編集をするわけではないです。
Unityで設定があるので、それをいじります。

圧縮の設定はテクスチャのInspectorにあるので、まずそれを探します。

テクスチャ圧縮したいオブジェクトを選択してください。

(今回はメッシュベイク&ライトベイクを済ませた家具を選択しています)

InspectorのMesh RendererのMaterialにMain Mapsというものが見つかります。
小さなアイコンをクリックしてください。すると左のフォルダがテクスチャ一覧になります。

フォルダ内にあるテクスチャを選択状態にするとInspectorに上記画像のようなものが表示されるので、このMax Sizeの数値を低くします。今回は4096になっていたので1024まで下げました。

必要に応じてもっと下げてもいいですが、その分汚くなっていきます。まあトレードオフってやつですね。
目立たない場所やクオリティを求めないオブジェクトはガンガン数値を下げてしまいましょう。

また、Compresser Qualityの数値を上げることでテクスチャの圧縮率が高まります。チェックボックスにチェックを入れるとバーが表示されるので、最大値の100まで上げるといいです。

この二つの圧縮でかなりの軽量化をおこなえますので、ワールドの容量が大きすぎて困っている人はぜひ。

Dynamic Materialsの数を整頓する

VRCWorldのInspectorを見ると、「Dynamic Materials」という項目があります。ワールド内に存在しているマテリアルの数です。

このElementの数が多いほど容量がデカくなっていくのですが、実はこのElement、一度オブジェクトをシーンにドロップしてしまうと、シーンから削除しても増えたままなのです。

なのでここのElementを消していかないと軽量化を試みても一向にサイズが減っていかないんですよね。

この解決方法は簡単で一度Dynamic MaterialsのSizeの値を0にし、New buildすることで本来の数値に戻ります。

これもかなりの軽量化になりますので、ぜひお試しあれ。

コメント

タイトルとURLをコピーしました