最初に、本記事のまとめです。
- UE4.25以前では、Static Switchなどを変更したマテリアルインスタンスはデータサイズがマテリアルと同等となってしまうという問題があり、それらを考慮して慎重にStatic Switchを使う必要がありました。
- UE4.25からは、デフォルトの設定では、Static Switchなどを使ってもマテリアルインスタンスのデータサイズが膨れることはなくなりました
- これは「Share Material Shader Code」というProject Settingsの項目がUE4.25でデフォルトでONになったためです。
- この設定によりマテリアルのロード時間の若干の増加が懸念されますが、Static Switchを多用するようなシーンでは逆にロードが速くなることもありました。
以下で詳細を確認していきます。
##Static Switch等によるマテリアルインスタンスのデータサイズ肥大問題
マテリアルには、静的に処理を分岐させるStatic Switchというノードがあります。これを使うことで、マテリアルインスタンス内でテクスチャの使用有無を切り替えたり、大きく処理を変更したりすることができ、マテリアルの管理がしやすくなります。便利な反面、このStatic Switchは使用するとマテリアルインスタンスのデータサイズが肥大するという副作用があり、注意して扱う必要がありました。
例えば、Byking様開発のマジシャンズデッドでは、ゲームパッケージのデータの60%がマテリアルインスタンスとなってしまうという問題が開発中に起きたとのことです。
この仕組みについては以下のスライドにまとめてありますので、ご興味のある方はご参考にして頂ければ幸いです。
#UE4.25から全プラットフォームでShare Material Shader CodeがONに
UE4.25からShare Material Shader CodeがデフォルトでONになりました。
この設定により、各マテリアル及びマテリアルインスタンスがシェーダを独自で持つことがなくなり、マテリアルが使うシェーダたちは.shaderbytecodeという一つのファイルにまとめられます。結果、Static Switchを使っても、各マテリアルインスタンスが独自でシェーダを持つことはなくなりました。
##データサイズの検証
簡単なシーンでマテリアルインスタンスでStatic Switchを使用したものを作成しばらまいてみて、パッケージングしてみました。
パッケージサイズの比較
Share material Shader Code: OFF | Share material Shader Code: ON | |
---|---|---|
Package Size | 337,024KB | 316,736KB |
このような単純なシーンでも、パッケージサイズが20MB近く減っているのがわかります。大規模なゲーム開発ではこの数百倍のマテリアルインスタンスが存在することもあるので、この差は非常に大きいと思います。 |
実際にStatic Switchを変更したマテリアルインスタンス56個のファイルサイズを見てみました。
各データサイズの比較
Share material Shader Code: OFF | Share material Shader Code: ON | |
---|---|---|
各マテリアルインスタンス一個のサイズ | 671KB | 78KB |
56個のマテリアルインスタンス合計のサイズ | 36.6MB | 4.24MB |
.ushaderbytecodeのサイズ | なし | 5,024KB |
確かにマテリアルインスタンスのデータサイズが減っています!(.ushaderbytecodeは他のマテリアルのシェーダコードも入っている点ご留意ください) |
ロード時間の検証
データサイズが減ってうれしいのですが、このオプションには”ロード時間が増加するかもしれない”という注意書きがあります。
実際にロード時間がどれくらい変化するか計測してみました。
ロード時間の比較
Share material Shader Code: OFF | Share material Shader Code: ON | |
---|---|---|
LoadMap時間 | 1,400.0ms | 394.7ms |
なんと嬉しいことに、このサンプルではShare Material Shader CodeをONにした方が速くなっています!!!Urneal Insightでロードがどうなっているかを確認してみます。
Share material Shader CodeがOFFのLoadMap
このオプションがOFFの場合は、各マテリアルインスタンスのロード時にファイル読み込み待ちが連続して発生しているのがわかります。
Share material Shader CodeがONのLoadMap
一方オプションがONの場合は各マテリアルインスタンスがIO待ちをせずにデシリアライズを続けていました。これがローディング時間が速くなった理由と思われます。
Static Switchを使用しないシーンではローディング時間が若干増加する懸念はあるのですが、Static Switchを使用しているマテリアルインスタンスに対してはロードが速くなるという利点があることがわかりました。
おしまい
ということで冒頭のまとめとなります。個人的には、これをOFFにすることはないんじゃないかなと思いました。**パッケージサイズを気にせずStatic Switchを自由に使えるというのは、マテリアルの運用方法の自由度を各段にあげることができます。**マテリアルインスタンスのサイズ問題は非常に知れ渡ったった問題で、Static Switchの使用を制限するチームもいたと聞きます。UE4.25以上のUEをお使いの方は、もう一度マテリアル運用方法を見直してみてもよいかもしれません。ご参考になれば幸いです。
UE4.25以上をお使いの方は、もうマテリアルでStatic Switchを自由に使える!かもしれません。https://t.co/uFO43RZtnQ #UE4 #UE5
— スミオ(SUMIO) (@tempkinder) December 29, 2021