UnityでのShaderLabメモリの最適化

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

一、問題を述べる

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

二、問題を分析する

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

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

究明のために、一輪の調査を回しました。Standardで使用されている場所のいくつかをクリアし、もう一度テストして、別のメモリスナップショットを作成しました。

クリアした後、ShaderLabは27.6 MBに低下しました(後で、スタンダードは完全にクリアされ、21 MBに低下しました)。やっぱり、主な原因はStandardにあります。じゃあ、また問題が発生しました。Standardを使用していませんのに、なぜメモリにStandardが存在してありますか?

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

三、問題を排除する

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

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

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

では、ソリューションも非常に簡単です。「Import Materials」を削除し、使用されていないデフォルトのマテリアルを削除します。

注:「Import Materials」を削除しないと、他のプロジェクトにインポートしたときにマテリアルがまた自動的に作成されます。

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

「Import Materials」をチェックしないモデルファイルは、Prefabをインスタンス化すると、ShaderLabには一つの「Standard」のShaderメモリがありますが、このShaderの参照は一つの「Default-Material」ファイルに指します(しかしこのファイルは存在してありません)。

ただし、モデルとPrefabが同じAssetBundleにあり、またはResourcesを使用してロードされている場合、「Standard」と「Default-Material」は顕示されません。Unity 5.3.3のバグなのか、Unityの特殊なメカニズムなのかはまだわかりません。

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

 

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

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

ただし、これはシステムのデフォルトのMeshであるから、作成時に指定されるマテリアルはデフォルトのマテリアル「Default-Material」であり、このマテリアルで使用されるシェーダーはたまたま「Standard」です。だから「Standard」の存在は間違いではありません。

解決策も非常に簡単です。これらのMeshを削除するか、マテリアルを交換します。 こうすれば、この部分が占める「Standard」は存在しません。

四、まとめ

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

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

 

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


UWA公式サイト:https://jp.uwa4d.com

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

UWA公式Q&Aコミュニティ(中国語注意):https://answer.uwa4d.com