UE4.25以降、デフォルトではStaticSwitch等によってマテリアルインスタンスのデータサイズが大きくなることはありません

最初に、本記事のまとめです。

- 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%がマテリアルインスタンスとなってしまうという問題が開発中に起きたとのことです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/68288e28-3fba-e634-19e6-f48d95e9a32c.png)
<iframe src="//www.slideshare.net/slideshow/embed_code/key/wLxXQI0cTLWIIM" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/EpicGamesJapan/byking-ue4dd" title="マジシャンズデッド ポストモーテム ~マテリアル編~ (株式会社Byking: 鈴木孝司様、成相真治様) #UE4DD" target="_blank">マジシャンズデッド ポストモーテム ~マテリアル編~ (株式会社Byking: 鈴木孝司様、成相真治様) #UE4DD</a> </strong> from <strong><a href="https://www.slideshare.net/EpicGamesJapan" target="_blank">エピック・ゲームズ・ジャパン Epic Games Japan</a></strong> </div>

この仕組みについては以下のスライドにまとめてありますので、ご興味のある方はご参考にして頂ければ幸いです。
<iframe src="//www.slideshare.net/slideshow/embed_code/key/fygbev80hokYRS" width="595" height="485" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="//www.slideshare.net/EpicGamesJapan/epic-games-japan-ue4dd" title="マテリアルとマテリアルインスタンスの仕組みと問題点の共有 (Epic Games Japan: 篠山範明) #UE4DD" target="_blank">マテリアルとマテリアルインスタンスの仕組みと問題点の共有 (Epic Games Japan: 篠山範明) #UE4DD</a> </strong> from <strong><a href="https://www.slideshare.net/EpicGamesJapan" target="_blank">エピック・ゲームズ・ジャパン Epic Games Japan</a></strong> </div>

#UE4.25から全プラットフォームでShare Material Shader CodeがONに
UE4.25からShare Material Shader CodeがデフォルトでONになりました。
<img width="400" alt="image" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/8bebf473-5ae5-483a-864d-88c40653f122.png">

この設定により、各マテリアル及びマテリアルインスタンスがシェーダを独自で持つことがなくなり、マテリアルが使うシェーダたちは.shaderbytecodeという一つのファイルにまとめられます。結果、Static Switchを使っても、各マテリアルインスタンスが独自でシェーダを持つことはなくなりました。

##データサイズの検証
簡単なシーンでマテリアルインスタンスでStatic Switchを使用したものを作成しばらまいてみて、パッケージングしてみました。

<img width="800" alt="image" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/40f73078-6538-1e35-8098-4a5c19453f2c.png">
<img width="800" alt="image" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/5aa9fa95-e509-1adc-8ed1-10058d70728b.png">

**パッケージサイズの比較**

|| 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は他のマテリアルのシェーダコードも入っている点ご留意ください）

## ロード時間の検証
データサイズが減ってうれしいのですが、このオプションには”ロード時間が増加するかもしれない”という注意書きがあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/107bffff-b329-4655-4062-8f7ed57aa679.png)
実際にロード時間がどれくらい変化するか計測してみました。

**ロード時間の比較**

|| 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の場合は、各マテリアルインスタンスのロード時にファイル読み込み待ちが連続して発生しているのがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/550318ce-44ca-09f6-9228-1351193c4000.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/74b1ec27-319f-068e-82c4-fe13bd93dfbf.png)


**Share material Shader CodeがONのLoadMap**
一方オプションがONの場合は各マテリアルインスタンスがIO待ちをせずにデシリアライズを続けていました。これがローディング時間が速くなった理由と思われます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/14b39c4e-86b1-c8af-d24a-d688cb4110b0.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363464/64dc121d-cdee-3e57-b574-87c08f66aeda.png)
Static Switchを使用しないシーンではローディング時間が若干増加する懸念はあるのですが、Static Switchを使用しているマテリアルインスタンスに対してはロードが速くなるという利点があることがわかりました。

## おしまい
ということで冒頭のまとめとなります。個人的には、これをOFFにすることはないんじゃないかなと思いました。**パッケージサイズを気にせずStatic Switchを自由に使えるというのは、マテリアルの運用方法の自由度を各段にあげることができます。**マテリアルインスタンスのサイズ問題は非常に知れ渡ったった問題で、Static Switchの使用を制限するチームもいたと聞きます。UE4.25以上のUEをお使いの方は、もう一度マテリアル運用方法を見直してみてもよいかもしれません。ご参考になれば幸いです。


<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">UE4.25以上をお使いの方は、もうマテリアルでStatic Switchを自由に使える！かもしれません。<a href="https://t.co/uFO43RZtnQ">https://t.co/uFO43RZtnQ</a> <a href="https://twitter.com/hashtag/UE4?src=hash&amp;ref_src=twsrc%5Etfw">#UE4</a> <a href="https://twitter.com/hashtag/UE5?src=hash&amp;ref_src=twsrc%5Etfw">#UE5</a></p>&mdash; スミオ（SUMIO） (@tempkinder) <a href="https://twitter.com/tempkinder/status/1476167456934993925?ref_src=twsrc%5Etfw">December 29, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>