LoginSignup
3
4

More than 3 years have passed since last update.

UnityでのShaderLabメモリの最適化

Posted at

おそらく、ShaderLabメモリの最適化に困っている開発者は多いでしょう。「価格の高い」メモリスペースに、無視できないボリュームを占めることがよくあります。他のアセットメモリと比べて、「ブラックボックス」に似ているので、最適化するのは難しいです。そのため、いくつかの実験を通じてShaderLabの占有率を分析し、この部分のメモリを最適化する方法を考えました。


一、問題を述べる

1.png
上の図(戦闘シーンに入ったときのメモリスナップショット)から、ShaderLabの占有率が42MBに達していることがわかります。なぜ、ShaderLabの占有率がそれほど高いのですか?

二、問題を分析する

2.png
現在のアイテム(ShaderLab)には詳細なShader占有情報を説明していませんので、他の方法で原因を探さなければなりません。 幸いなことに、メモリスナップショットのAssetsの下のShaderアイテムに詳細な使用情報があります。

そして、StandardのShaderが使用されているのを見ましたが、このプロジェクトにStandardのShaderを使用する場所がありませんので、なぜ存在していますか?

究明のために、一輪の調査を回しました。Standardで使用されている場所のいくつかをクリアし、もう一度テストして、別のメモリスナップショットを作成しました。
3.png
クリアした後、ShaderLabは27.6 MBに低下しました(後で、スタンダードは完全にクリアされ、21 MBに低下しました)。やっぱり、主な原因はStandardにあります。じゃあ、また問題が発生しました。Standardを使用していませんのに、なぜメモリにStandardが存在してありますか?

ここでは二点について話す必要があり、これもこの問題を排除する方法であります。

三、問題を排除する

1.モデルのインポートが導く

モデルをインポートする時、デフォルトで「Import Materials」がチェックされます。モデルがインポートされると、Unityは同じディレクトリに「Materials」ディレクトリを作成し、対応するマテリアルを作成します。このマテリアルはデフォルトでStandardを使用します。

アーティストが製造の過程にPrefabにあるモデルに他のマテリアルを添付しますので、実にはデフォルトのマテリアル(Standard)は使用されません。ただし、モデルをロードすると、デフォルトで作成されたマテリアルが再度ロードされ、シェーダーに解析され、メモリ内でStandardがあるになります。

では、ソリューションも非常に簡単です。「Import Materials」を削除し、使用されていないデフォルトのマテリアルを削除します。
4.png
注:「Import Materials」を削除しないと、他のプロジェクトにインポートしたときにマテリアルがまた自動的に作成されます。

補足:実際のプロジェクトでは、Prefabの変更回数は比較的多く、対応するモデルファイルの変更は比較的少ないため、プロジェクトのモデルと対応するPrefabは別々のAssetBundleにパッケージ化すると、非常に奇妙な状況が発生します。

「Import Materials」をチェックしないモデルファイルは、Prefabをインスタンス化すると、ShaderLabには一つの「Standard」のShaderメモリがありますが、このShaderの参照は一つの「Default-Material」ファイルに指します(しかしこのファイルは存在してありません)。
5.png
ただし、モデルとPrefabが同じAssetBundleにあり、またはResourcesを使用してロードされている場合、「Standard」と「Default-Material」は顕示されません。Unity 5.3.3のバグなのか、Unityの特殊なメカニズムなのかはまだわかりません。

一時的な解決策:モデルをPrefabとは別にパッケージ化する必要がある場合は、「Import Materials」をチェックして、デフォルトで生成された材料を直接使用および変更します。

2.デフォルトモデル(Cube、Sphere)の作成が導く

初期のシーンを構築する時、配置や視覚化しやすいのために、CubeみたいなシステムのデフォルトのMeshがアンカーポイントとして使用され、ゲームを始まる時に禁止させます。これらのCubeは有効になっていないため、パフォーマンスのコストはごくわずかであるため、無視します。

ただし、これはシステムのデフォルトのMeshであるから、作成時に指定されるマテリアルはデフォルトのマテリアル「Default-Material」であり、このマテリアルで使用されるシェーダーはたまたま「Standard」です。だから「Standard」の存在は間違いではありません。
6.png
解決策も非常に簡単です。これらのMeshを削除するか、マテリアルを交換します。 こうすれば、この部分が占める「Standard」は存在しません。

四、まとめ

Standardの変種が多すぎるため、Standardを使用しますと、複数のStandardの変種が同時に存在することがよくあり、大量のメモリを占めます。ShaderLabのメモリが大きすぎと感じっている場合は、上記の原因ですかどうかを調べてみてください。

ShaderLabのメモリ占用が大きすぎとは、完全にStandardの原因ですか?実際にはもっとあります。最適化後の27MB(完全にクリアされた後の21MB)の中に、他の原因があるはずです。しかし、最適化の過程は大きな部分から削除し始まることです。上記のように、少し最適化したら20MB以上を改善できますし、もちろんすぐにやる必要がありますが。サイズが小さいほど最適化効率は低くなるので、現時点では 「Assets」や「Texture2D」などの部分に目差して最適化します。したがって、残ったShaderLabの最適化方法は後であった時に再び補充します。

PS:上記の全ての内容は実機でテストしました。


UWA Technologyは、モバイル/VRなど様々なゲーム開発者向け、パフォーマンス分析最適化ソリューション及びコンサルティングサービスを提供している会社でございます。

UWA公式サイト:https://jp.uwa4d.com
UWA公式ブログ:https://blog.jp.uwa4d.com

3
4
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
3
4