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

VRChat

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

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

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

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

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

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

メッシュをベイクする

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

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

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

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

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

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

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

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

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

【Unity's Black Friday Week Sale】Mesh Bakerの使い方記事! VRChat民のアバター・ワールドが少しでも軽くなるように! アバターのメッシュとマテリアルを1つに結合する方法を簡単に解説します(ワールドも)!2018年11月21日 V3.26.1 「Mesh Baker」 - Unity AssetStoreまとめ

ライトをベイクする

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

ライトのモード ライトの種類はModeから選択できます。

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

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

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

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

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

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

ライトマップのベイク とライトプローブ|ぷもん|note

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

【Unity】ライトマップのベイク時間を短時間で終わらせる - テラシュールブログ

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

なんかメッシュベイクしてからライトのベイクをしたらおかしくなりました。 完全に焼け焦げています。

また同じ現象に遭遇したときに自分で解決できるように書き残しておこうと思います。

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

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

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

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

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

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

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

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

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

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

VRChat ワールド軽量化のための設定+オクルージョンカリングについて|Kluele_VRC|note

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

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

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

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

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

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

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

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

モデルデータの書き出しサイズを小さくする Mesh Compression - Unityな日々(Unity Geek)

テクスチャの圧縮をする

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

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

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

テクスチャのアイコン (今回はメッシュベイク&ライトベイクを済ませた家具を選択しています)

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

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

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

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

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

Dynamic Materialsの数を整頓する

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

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

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

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

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

広告

関連記事

新着記事

広告

ログインが必要なページからjsoupでスクレイピングする方法【Java】
VRChatを快適プレイできるスペックと、それを整えるのに必要なお金はどのくらい?