75.6K Views
October 07, 19
スライド概要
講演動画:https://youtu.be/A_l65FlY25I
Part 1:https://www.slideshare.net/EpicGamesJapan/ue4-festeast2019-ue4mobilepart1-179705324/
2019年10月6日に行われた「UNREAL FEST EAST 2019」で登壇した際に使用した資料です。
●公式サイト
https://unrealengine.jp/unrealfest/
===
シェーダコンパイルによるカクツキなどモバイルゲーム開発特有の問題は数多くあり、それらはユーザのストレスに繋がる可能性があります。UE4はそういった問題に対しての機能を持っていますが、用法・用量を守って正しく使わないと別の問題を引き起こしてしまいます。そこで本講演ではそれらの機能の使い方、注意点などについて解説します(他のプラットフォーム開発でも役立つ内容にする予定です)。あ、今年は1人講演です。
Unreal Engineを開発・提供しているエピック ゲームズ ジャパンによる公式アカウントです。 勉強会や配信などで行った講演資料を公開しています。 公式サイトはこちら https://www.unrealengine.com/ja/
そう、UE4ならね。 あなたのモバイルゲームをより快適にする 沢山の冴えたやり方について Part2 Epic Games Japan Support Engineer 岡田和也
本スライド、300ページ超えだったせいなのか Slideshareへのアップに失敗しました /(^o^)\ そのため、Part1, 2に分割しています Part 1のURLに関しましては Slideshareの説明文をご確認ください
本日のお品書き ヒッチ対策 編 ● ● ● そもそもヒッチってなに? 一般的なヒッチ対策について モバイル特有のヒッチ対策について メモリ管理 編 ● ● なぜモバイル開発において問題になるのか メモリに関するプロファイル方法について 最新情報 編 ● UE4.23 で入った モバイル関連の便利機能・最適化について
モバイル特有のヒッチ対策について ● Shader Compile 問題 ● メモリ転送速度 問題
Mannequinのテクスチャが描画されるまでの流れ Storage Memory GPU
モバイル端末におけるメモリ 端末の発熱・電力消費を抑えるため 低電圧・低消費電力版である LPDDR (Low Power DDR) メモリを採用 メインメモリからGPUに データを送る速度・量が制限されている ● 転送速度、帯域幅
モバイルの場合… 大量 または サイズが大きい テクスチャを使った場合 メインメモリからGPUへの送信に時間がかかり、ヒッチの原因に GPU Memory PC環境 モバイル SoC
一般的な対策について (モバイル以外の環境でも有効)
…の前に UE4でTextureを語る際に避けては通れない Texture Streaming機能に関して軽く紹介
Texture Streamingについて Textureの MipMap の読み込みと破棄を動的に行い、 MemoryのTexture使用量を一定以下に保つ機能 Storage Memory GPU
Texture Streaming のメリットの一つ 4K などの巨大なテクスチャであっても Mipが生成されているなら、適切(と判断された)サイズのみをロード
つまり… Mipがない 場合や Texture Streamingを無効 にした場合、 ヒッチ、ロード時間増加、メモリ使用量などの問題が発生 4K! 4K! 4K!
Texture Streamingと どれだけ仲良くできるかが勝利の鍵です!
テクスチャの サイズ、圧縮設定は適切に
テクスチャのサイズは… 圧縮のために 4の倍数に Mipmap ( Texture Streaming ) のために 2のべき乗に ● パッケージサイズを考慮すると、必要十分なサイズであることも重要 1999 x 1999 無圧縮: 15.6MB 2048 x 2048 ASTC: 1.82MB
イカロスMにおけるロードイメージの最適化Tips 2のべき乗に変換した Texture を Material で復元 ● 14.2MB から 2MB にサイズ削減 (86%削減) ソース 2738 x 1332 変形 2048 x 2048 復元 2738 x 1332
● https://replay.unrealsummit.co.kr/data2019/USM20190515_2_1.html
テクスチャの圧縮フォーマット ( for モバイル ) Android ゲームの開発のリファレンス https://api.unrealengine.com/JPN/Platforms/Android/Reference/index.html
できるだけ Texture Streamingは使いましょう
Never Stream は 可能な限り避ける ロードが間に合わずテクスチャがボケることを回避するために Never Streamを有効( = Texture Streaming を無効 )にすると…
Never Stream は 可能な限り避ける テクスチャの初回使用時に 全Mipのロードが開始 & 完了待ちするため、ヒッチ・ロード時間増加の原因に
(できるだけ)ボケたテクスチャが見えないように 公式ドキュメント ● https://docs.unrealengine.com/ja/Engine/Content/Types/Textures/Streami ng/index.html Qiita ● ● ● [UE4] Texture GroupがTexture Streamingに与える影響 [UE4] StreamingされないTextureはStreaming Texture Poolに入るのか?? [UE4] Texture Streaming Pool Over Budgetの意味 Slideshare ● UE4のシーケンサーをもっともっと使いこなそう!最新情報・Tipsをご紹介! (p113~)
Mipmap設定 UIなどMipmap( TextureStreaming )がNGなテクスチャの場合 必ずNoMipmaps設定に
Mipmap設定 UIなどMipmap( TextureStreaming )がNGなテクスチャの場合 必ずNoMipmaps設定に Resource Size : 5461 Kb Number of Mips : 12 Resource Size : 4096 Kb Number of Mips : 1
これらはどのプラットフォームでも 有効なTipsです!是非活用してきましょう!
ほぼモバイル特有のTips 1フレーム間に メインメモリ から GPUに送信する テクスチャ数を制限することでヒッチを回避
???????? ????????
レベルをロードしたときなど メモリからGPUに大量のテクスチャが転送されるとヒッチが起きる
ActionRPG タイトルからメインレベルに遷移したとき 検証端末:Xperia Z5 ( 2015年10月発売 )
ActionRPG タイトルからメインレベルに遷移したとき 157.9 ms FTexture2DStreamIn_IO_ AsyncReallocate:: AsyncReallocate : 約5フレーム(30fpsの場合) Calls : 68 検証端末:Xperia Z5 ( 2015年10月発売 )
1フレーム間にメインメモリからGPUに送信する テクスチャ数を制限する設定 r.Streaming.AmortizeCPUToGPUCopy ● ● 0:無効 ( デフォルト ) 1:有効 r.Streaming.MaxNumTexturesToStreamPerFrame ● ● テクスチャの最大送信数 デフォルト:0
比較結果 デフォルト ● 158.3 ms ( Calls : 68 ) r.Streaming.MaxNumTexturesToStreamPerFrame:5 ● 9.7 ms ( Calls : 5 ) 1フレームにおける負荷を 約150ms節約!
図で流れを説明! (説明の都合で簡略化してる部分あります)
2枚のテクスチャをロードする場合
まずは、最も低解像度の Mip をブロッキング (同期) ロード ストレージからGPU まで一気に送信
優先度の高いTexture から順に各 Mip をメインメモリへ
優先度の高いTexture から順に各 Mip をメインメモリへ
メインメモリに送られたテクスチャは 次はGPUに送られますが…
メインメモリに送られたテクスチャは 次はGPUに送られますが…
モバイルの場合 メインメモリからGPUへの転送速度が遅いので、CPU負荷が上がり…
モバイルの場合 メインメモリからGPUへの転送速度が遅いので、CPU負荷が上がり… \ヒッチ発生 /
r.Streaming. MaxNumTexturesToStreamPerFrame を 1に設定すると…
1フレームにつき メインメモリ から GPU に送るテクスチャが 1枚だけになるので
CPU負荷が下がりヒッチを回避!
そして、次のフレームでは 残りのテクスチャがメインメモリからGPUに
ざっくりまとめると メインメモリからGPUに 一度に 大量の テクスチャを送ると CPU負荷が一気に増えるので、送る枚数を制限しましょう という機能
注意! 低解像度のテクスチャが ユーザに見えてしまう可能性が増えます!
制限によってGPUに送信されなかったテクスチャは 最も低解像度のMipが描画に使われる
ロード対象のテクスチャの枚数、制限の値によっては 各MipがGPUに送信されるのが数フレーム以上後になる場合が…
r.Streaming.MaxNumTexturesToStreamPerFrame ハイエンドな端末では 高めの数値 又は 制限OFFに ローエンドな端末では 低めの数値に カットシーンなどボケて欲しくない場面は 動的に 制限OFF にする手も の設定は慎重に
設定例 [TextureQuality@0] r.Streaming.AmortizeCPUToGPUCopy=1 r.Streaming.MaxNumTexturesToStreamPerFrame=5 [TextureQuality@1] r.Streaming.AmortizeCPUToGPUCopy=1 r.Streaming.MaxNumTexturesToStreamPerFrame=10 [TextureQuality@2] r.Streaming.AmortizeCPUToGPUCopy=1 r.Streaming.MaxNumTexturesToStreamPerFrame=15 [TextureQuality@3] r.Streaming.AmortizeCPUToGPUCopy=1 r.Streaming.MaxNumTexturesToStreamPerFrame=20
おまけ ストレージからメモリへの送信数を制限することも可能 r.Streaming.FramesForFullUpdate ● IOネックの場合はこちらの設定を要調整 r.Streaming.FramesForFullUpdate r.Streaming.AmortizeCPUToGPUCopy
ここまでのまとめ モバイル端末のメインメモリからGPUへの転送速度は遅いため、 大量 又は 大容量のテクスチャをロードするとヒッチの原因になる Texture Streamingを考慮した設定にすることで 転送するテクスチャの量・サイズを調整することが大事 モバイルの場合、 1フレーム間でのテクスチャ転送数を制限することも検討
モバイル特有のヒッチ対策について ● Shader Compile 問題 ● メモリ転送速度 問題
ながいたたかいでした その成果がこちら
Before After https://youtu.be/tETCfRlxH5Q
初回起動時の負荷を比較 ( 左:未対策 右:対策導入済 )
初回起動時の負荷を比較 ( 左:未対策 右:対策導入済 ) Open Levelでレベルを開いた際の負荷 ローディング画面中なのでセーフ
初回起動時の負荷を比較 ( 左:未対策 右:対策導入済 ) PSOキャッシュの効果により シェーダコンパイル負荷がなくなった
初回起動時の負荷を比較 ( 左:未対策 右:対策導入済 ) メインメモリからGPUへのテクスチャ送信数を制限した効果 ヒッチは改善したが、数フレームに渡って少し速度が不安定に
改善の余地はまだまだありますが… 今回の目標である ヒッチの回避は実現できました!
やってやりました
こうして実際の動作を見てみると 違いは一目瞭然! 事前準備や各調整コストはありますが ゲームの完成度を一気に上げることができます!
本日のお品書き ヒッチ対策 編 ● ● ● そもそもヒッチってなに? 一般的なヒッチ対策について モバイル特有のヒッチ対策について メモリ管理 編 ● ● なぜモバイル開発において問題になるのか メモリに関するプロファイル方法について 最新情報 編 ● UE4.23 で入った モバイル関連の便利機能・最適化について
Shader Compile や テクスチャ から 急にメモリの話になります ごめんなさい (でも、実は関連してるんです)
どんなプラットフォームでも メモリ使用量が上限値を超えると クラッシュ わかる
モバイルの場合、 端末ごとにメモリ容量が異なるため 上限値も端末によって異なる …わかる
上限値 ≠ 端末のメモリ容量 端末毎に使用できる割合が異なるが そのルールが不明 わからん つらい…
とあるプロジェクトにおける計測結果 Galaxy S8 3.0GB / 4.0GB (75%) Pixel 2 1.8GB / 3.6GB (50%)
そもそも、メモリ使用量という概念が曖昧 最終的にクラッシュの判定で使われる値は 様々な要素が絡み合った結果の値 もう だめぽ
GDC2018のEpic講演で共有されたメモリに関する情報 iOS ● ● ● ● < 1.4 GB for 2 GB device ( 6, 7, 8 ) < 2.1 GB for 3 GB device ( Plus, X, XR ) < 2.8 GB for 4 GB device ( XS, 11 ) Xcode の Memory Usage Gauge による計測値 Android ● ● ● 0.5 GB for 2 GB device 1.4 GB for 3 GB device adb shell dumpsys meminfo による計測値
GDC2018のEpic講演で共有されたメモリに関する情報 iOS ● ● ● < 1.4 GB for 2 GB device ( 6, 7, 8 ) < 2.1 GB for 3 GB device ( Plus, X, XR ) < 2.8 GB for 4 GB device ( XS, 11 ) これらの値をそのまま使うのは非推奨です Android ゲーム内容 や シェーダの使い方などで目標値は大きく変化します! ● ● 0.5 GB for 2 GB device 1.4 GB for 3 GB device
とはいえ… 開発する上で、 レギュレーション(Budget)は 決める必要があります… また、普段の開発でも 定期的な計測は必須…
ターゲットとする端末毎に 必ず計測・検証しましょう! 各メモリプロファイラの 特性を把握した上で計測しましょう!
ターゲットとする端末毎に 実機での計測・検証することが大事 ● どのプロファイラの ● どの値が ● どの程度の値になったらクラッシュするか
各メモリプロファイラについて
UE4標準のメモリプロファイラについて (モバイル以外のプラットフォームでは挙動が異なる部分あります)
stat unit UE4が計測した値ではなく、 OS から取得した 物理メモリ使用量 の値を表示 (簡易版なので精度は低い) ● FPlatformMemory::GetMemoryUsedFast();
stat LLM / LLMFULL / LLMPlatform UE4が用意しているメモリ使用量を追跡するシステム カテゴリ毎にTag付け(独自Tag追加可能) ● LLM, LLMFULL : UE4 によって割り当てられたメモリ ● LLMPlatform : OSによって割り当てられたメモリ
ちなみに Total ( LLM Platform ) = Total ( LLMFULL ) + Overhead ( LLM Platform ) = stat unit の Mem 597.63 = 584.72 + 12.91
みんな大好き csv形式 でも出力できるよ!
使い方・Tips・注意点について 公式ドキュメント ● Low-Level Memory Tracker Qiita ● [UE4] LLM (Low Level Memory Tracker)を使用したメモリトラッキング
OS標準のメモリプロファイラについて
Android 編
adb shell dumpsys meminfo <PACKAGE_NAME> Google公式ドキュメント https://developer.android.com/ studio/command-line/ dumpsys#meminfo
adb shell dumpsys meminfo <PACKAGE_NAME> Google公式ドキュメント https://developer.android.com/ studio/command-line/ dumpsys#meminfo
No LRU cache – 2.22 GB RAM used LRU cache – 2.05 GB RAM used
iOS 編
Xcode / memory gauge
Instruments / Activity Monitor
Instruments / Activity Monitor
Instruments / Activity Monitor
Instruments / Allocations / VM Tracker
Instruments / Allocations / VM Tracker
iOS標準の メモリプロファイラの使い分けについて
Xcode, Activity Monitor ● 非常にシンプルで分かりやすい ● Activity Monitor は プロセスにAttachしなくてもいいので楽 ● 表示している値がどういう値なのか不明
Allocations ● メモリに関する詳細な情報を確認できる ● iOSのメモリ管理に関する深い知識が必要 ● 各項目がどのように作用してクラッシュの閾値になるかは不明
iOSのメモリ管理・使用量に関する挙動は 端末だけでなくプロジェクト毎に変化 Epicでも自信を持って 公開できる詳細なルール・方針がまだないほど 非常に複雑な問題 個人的考え ● Allocationsを駆使するのがベストですが… Xcode, Activity Monitor で妥協するのも悪くない選択肢
メモリプロファイラに関するまとめ
UE4標準のプロファイラ どのカテゴリ、アセットが問題になっているかを計測可能 使いやすいし、ひと目で分かりやすい OSとドライバによってメモリに割り当てられる GPUリソースは計測が不可能
OS標準のプロファイラ UE4標準ツールでは計測不可能な領域も計測可能 クラッシュの判定で使われる値は 表示してくれない ● 各OSにおける メモリ管理の仕組みを把握する必要がある
これらの特性を理解した上で プロジェクトにとって 適切なワークフローを構築しましょう! 例: stat LLM, OS標準ツールで日々プロファイル stat LLMは上がってないのに後者が向上していたら 描画周りでなにか問題がある?
ここまで紹介した手法は どの機能・カテゴリにおけるメモリ使用量が 問題になってるのかを知るためのもの 具体的にどのアセット・処理が 問題になっているか別の方法で調査!
参考資料 公式ブログ ● ● デバッグとメモリーの最適化 アンリアル エンジン 4 のメモリリーク対策 ● [CEDEC2017] UE4プロファイリングツール総おさらい(グラフィクス編) Slideshare 魔法の呪文 ● memreport –full
おまけ
Xcode 11 で 新しいメモリプロファイル機能が! WWDC 2019 Delivering Optimized Metal Apps and Games https://developer.apple.com/videos/play/wwdc2019/606/
Xcode 11を使う際は UE4.23 以降の エンジンバージョンをお使いください!
ここまでのまとめ モバイルの場合、アプリが使える メモリ上限値が端末ごとに異なる上に、その値が明確ではない プロファイリングは大事 UE4 には メモリ追跡用の機能が複数用意されている Android, iOSに用意されている メモリ追跡機能を使うことで、より詳細な調査もすることが可能
本日のお品書き ヒッチ対策 編 ● ● ● そもそもヒッチってなに? 一般的なヒッチ対策について モバイル特有のヒッチ対策について メモリ管理 編 ● ● なぜモバイル開発において問題になるのか メモリに関するプロファイル方法について 最新情報 編 ● UE4.23 で入った モバイル関連の便利機能・最適化について
最後は たのしいはなしで 終わりましょう!!!
Added experimental support for auto-instancing on mobile [Experimental] UE4.23 リリースノートより
複数のモデルを一度に描画することで Draw Call を削減するTipsは有名
Merge Actor HLOD (Hierarchical Level of Detail) Instanced Static Mesh Foliage
デメリットもあるので 要注意! 処理負荷が 逆に増えるケースも! UE4アセットリダクション手法紹介
デメリットの話は一旦置いておいて… Static Meshの Draw Callをまとめる機能は用意されていましたが、 ● ● ● 静的なオブジェクト限定 セットアップなどの作業コスト 融通があまり利かない などの問題がありました
Auto-instancing on mobile メッシュ描画パイプライン が 新しくなったことで 可能な場合は、自動的にDraw Callをまとめるように! (モバイル以外のプラットフォームは UE4.22から)
使うためには DefaultEngine.ini にて [/Script/Engine.RendererSettings] r.Mobile.SupportGPUScene=1 デフォルト:0(無効)
検証環境 Cube : 500 ( 48 ポリ * 500 = 24000 ポリ) Movable Directional Light : 1 検証端末:Xperia Z5 ● ● Snapdragon 810 2015年10月発売
Auto Instancing : OFF Auto Instancing : ON
Auto Instancing : OFF Auto Instancing : ON
せっかくなので もっと出してみました 検証端末:iPhone X お見せする動画は6倍速にしています
https://youtu.be/SxjSWgy9U_g
Auto Instancing on Mobile のいいところ 事前セットアップが不要 Movable な Static Meshも Instancingの対象に! Frame Game : 25.99 ms : 13.64 ms Frame Game : 16.68 ms : 12.33 ms Mem : 319.6 MB Mem : 297.6 MB Prims : 301.6K Prims : 295.9K Draw : 27.70 ms Draws : 6175 Draw : 15.74 ms Draws : 54
注意点 公式ドキュメント https://docs.unrealengine.com/ja/Programming/Rendering/MeshDrawing Pipeline/index.html ● Auto Instancingを行うための処理の負荷が加算 ● モバイルでは Static Light を無効にする必要あり ● Auto Instancingの対象になるには 幾つかの条件を満たす必要あり ● 現在Mali端末では正常に動作しない(修正中)
この他にも様々な機能追加・最適化が入っています! 是非リリースノートをご確認ください! https://docs.unrealengine.com/ja/Support/Builds/Rele aseNotes/4_23/index.html
今回のまとめ モバイル特有のヒッチ対策について ● ● Shader Compile: PSOキャッシュなどの便利機能を活用! メモリ転送速度: アートとシステム、両面から対応することで対策可能 メモリ対策について ● UE4標準のメモリ追跡機能について ● Android, iOSのメモリ追跡機能について モバイルに関する最新機能について ● Auto Instancing for Mobile
参考資料 ● 『修羅道』制作事例 モバイルハイエンドグラフィックゲーム実現まで ● UE4モバイルブートキャンプ ● UE4モバイルでノンゲームコンテンツ ● 【CEDEC2018】Android ハイパフォーマンス・プログラミング ● CEDEC 2016 Metal と Vulkan を用いた水彩画レンダリング技法の紹介 ● 玄人向けAndroid/iOS対応エンジン 開発レポート ● HYPERでんち さん ● https://www.slideshare.net/EpicGamesJapan/ss-119696520 ● https://www.slideshare.net/EpicGamesJapan/ue4mobilebootcamp ● https://www.slideshare.net/EpicGamesJapan/ue4-mobilenongame ● https://www.youtube.com/watch?v=oxJWWCYWRlY ● https://www.slideshare.net/drecom/cedec-2016-metal-vulkan ● https://cedil.cesa.or.jp/cedil_sessions/view/2035 ● https://dench.flatlib.jp/
参考資料 ● Optimizing UE4 for Fortnite: Battle Royale - Part 1,2 ● Epic Games Wang Wei:UE4のマルチプレイヤーゲームの最適化 ● Using UE4 to Develop for Oculus Rift and Oculus Quest ● ARK on iOS: Leveraging UE4 for 98% Content Reduction ● ARK on iOS: Coding and Design Tips for Truly Unreal Success on Mobile ● Developer Perspective: Improving Memory Usage and Load Times in UE4 ● Developer Perspective: UE4 Logging and Console Commands for Mobile VR ● ● https://www.youtube.com/watch?v=KHWquMYtji0 https://www.youtube.com/watch?v=1xiwJukvb60 ● https://zhuanlan.zhihu.com/p/43742565 ● https://www.youtube.com/watch?v=hEtu-ciPc7g ● https://www.unrealengine.com/ja/events/unreal-fest-europe-2019/ark-on-ios-coding-and-design-tips-fortruly-unreal-success-on-mobile?lang=ja ● ● ● https://www.unrealengine.com/ja/events/unreal-fest-europe-2019/ark-on-ios-leveraging-ue4-for-98content-reduction?lang=ja https://developer.oculus.com/blog/developer-perspective-improving-memory-usage-and-load-times-inue4/ https://developer.oculus.com/blog/developer-perspective-ue4-logging-and-console-commands-for-mobilevr/
参考資料 <WWDC> ● Delivering Optimized Metal Apps and Games ● Metal Shader Debugging and Profiling ● Metal for Game Developers ● Metal 2 Optimization and Debugging ● https://developer.apple.com/videos/play/wwdc2019/606/ ● https://developer.apple.com/videos/play/wwdc2018/608/ ● https://developer.apple.com/videos/play/wwdc2018/607/ ● https://developer.apple.com/videos/play/wwdc2017/607/
参考資料<Unreal Summit> ほぼ全て韓国語です Google翻訳先生に頼りましょう ● Unreal Engineの4のタイルレンダリング活用する ● シェーダパイプラインキャッシュ(PSOキャッシュ)本番の使い方 ● UE4:アンドロイドバルカン最適化ホワイトペーパー ● マルチプラットフォームのアートコンテンツの最適化:アーティスト編1 ● マルチプラットフォームのアートコンテンツの最適化:アーティスト編2 ● マルチプラットフォームの最適化:プログラマ編 ● 快適なイカルスMのプレイを完成したUnreal Engineの4 - 最適化と安定化、機能の使用のためのケースを共有 ● イカルスMポストモトム - モバイルMMORPGの最適化、クオリティのTA苦労機 ● L2M Unrealの使用期限 ● https://replay.unrealsummit.co.kr/data2019/USM20190515_1_4.html ● https://replay.unrealsummit.co.kr/data2019/USM20190514_1_5.html ● https://replay.unrealsummit.co.kr/data2019/USM20190514_1_4.html ● https://replay.unrealsummit.co.kr/data2019/USM20190514_2_2.html ● https://replay.unrealsummit.co.kr/data2019/USM20190514_2_3.html ● https://replay.unrealsummit.co.kr/data2019/USM20190515_1_2.html ● https://replay.unrealsummit.co.kr/data2019/USM20190515_1_1.html ● https://replay.unrealsummit.co.kr/data2019/USM20190515_2_1.html ● https://replay.unrealsummit.co.kr/data2019/USM20190514_1_1.html
ご清聴ありがとうございました!