Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
そう、UE4ならね。
あなたのモバイルゲームをより快適にする
沢山の冴えたやり方について Part1
Epic Games Japan
Support Engineer 岡田和也
本日のハッシュタグ
#ue4fest
スライドは近日公開予定
しました
本スライド、300ページ超えだったせいなのか
Slideshareへのアップに失敗しました /(^o^)\
そのため、Part1, 2に分割しています
Part 2のURLに関しましては
Slideshareの説明文をご確認ください
自己紹介
Epic Games Japan サポートエンジニア
岡田 和也
Twitter:
おかず ( @pafuhana1213 )
ライセンシのサポート業務や講演が主なお仕事
最近モバイル担当してます
国内のUE4モバイルタイトル
増えてきました…!
国内のUE4製モバイルタイトル
New!
VARIOUS DAYLIFE(バリアスデイライフ)
Apple Arcade にて 絶賛配信中!
UE4モバイルタイトルに携わる人向けに
より実践的な話をせねば…!
これまでのUE4モバイルに関する講演を
振り返ってみると…
モバイル関連の機能・最新情報紹介
最新モバイルゲームの実例からみるUE4のモバイル向け機能・Tipsを
全部まるっとご紹介! + UE4.18 モバイル最新情報の紹介
https://www.slideshare.net/EpicGamesJa...
コンテンツアップデートについて
UE4のモバイル開発におけるコンテンツアップデートの話
- Chunk IDとの激闘編 –
https://www.slideshare.net/EpicGamesJapan/ue4-chunk-id
徹底解説!...
某ブログにて
【UE4 & Android】実機デバッグ実行中のログ確認方法について
http://pafuhana1213.hatenablog.com/entry/2019/02/20/013340
UE4 & iOS開発時の実機デバッグ・...
振り返ってみると…
モバイル開発において避けることができない
モバイル特有のヒッチ
メモリ問題
についてガッツリ話したことがない!
ユーザのストレス・継続率に
大きく影響する重要な問題
これらの問題に対する対策が
不十分な場合、様々な問題が発生します
たとえば…
● プレイ中のカクツキ
● 長時間ロード
● 発熱からのパフォーマンス低下
● 猛烈に減る電池
● 突然のクラッシュ
● などなどなど…
やばい
早い段階から対策を入れることで
ゲームをより快適にしていきましょう!
(普段の開発も快適に!)
本日のお品書き
ヒッチ対策 編
● そもそもヒッチってなに?
● 一般的なヒッチ対策について
● モバイル特有のヒッチ対策について
メモリ管理 編
● なぜモバイル開発において問題になるのか
● メモリに関するプロファイル方法について
最新情報...
そもそもヒッチってなに?
ヒッチ( Hitch )とは?
● 引っかける
● (くいなどに)つなぐ
● (…を)ぐいと動かす
● (ヒッチハイクで)させてもらう
● ヒッチハイクで行く
Weblio英和辞書 より
いわゆる、カクつき
ゲームにおけるカクつき
それまで滑らかに動いていたのが
急にカクついたり、一定時間画面が止まったり…
https://youtu.be/6oR9GWGgBZY
イライラがすごい
海外だとHitchと表現することが多いため
本講演もそれに倣います
Google先生に聞くときもこれを意識するのオススメ!
ヒッチは なぜ / いつ 起きる?
あるフレーム(タイミング)で
非常に負荷が重い処理 、
または 大量の処理 が実行されたときに発生
ヒッチは なぜ / いつ 起きる?
あるフレーム(タイミング)で
非常に負荷が重い処理 、
または 大量の処理 が実行されたときに発生
ヒッチを回避するには
どうすればいいのか?
ヒッチ対策の基本的な方針 その1
負荷 を 削減
ヒッチ対策の基本的な方針 その2
処理の数 を 削減
ヒッチ対策の基本的な方針 その3
大量の処理 を 複数フレーム に 分散
ヒッチ対策の基本的な方針 その3.5
大量の処理 を 複数フレーム に 分散
ヒッチ対策の基本的な方針 その4
重い処理 を 複数フレーム に 分散
ここまでのまとめ
ヒッチを回避するには
どうすればいいのか?
負荷を 削減 ・分散する
本日のお品書き
ヒッチ対策 編
● そもそもヒッチってなに?
● 一般的なヒッチ対策について
● モバイル特有のヒッチ対策について
メモリ管理 編
● なぜモバイル開発において問題になるのか
● メモリに関するプロファイル方法について
最新情報...
ヒッチが起きやすいタイミング
● アセット・レベルのロード
● オブジェクトの生成
● ガベージコレクション(GC)
アセットのロード数を 削減
アセット間の参照関係を整理
● 直接参照の場合
連鎖的にロード処理が走るため
Unreal Fest East 2018
Nintendo Switch『OCTOPATH TRAVELER』は
こうして作られた
ht...
レベルを複数のサブレベルに分割
● 必要に応じてロード・アンロード
● ロードタイミングの分散
アセットのロード数を 削減・分散
アセットのロード数を 分散
実際に使われる前に事前ロード(前読み)
Qiita:Asset Managerのアセットの非同期ロード機能について
ヒッチが起きやすいタイミング
● アセット・レベルのロード
● オブジェクトの生成
● ガベージコレクション(GC)
動的にActorを生成すると…
アセットのロード後に各初期化処理が走る
● Construction Script, Begin Playなど
BP_Bullet
オブジェクトの生成処理を 削減・分散
● Construction Script, Begin Play における処理の削減・分散
● 生成タイミング自体を分散
● オブジェクトプール(常駐・使い回し)で分散
ヒッチが起きやすいタイミング
● アセット・レベルのロード
● オブジェクトの生成
● ガベージコレクション(GC)
GCの対策
この資料読んで!以上!
[4.20版] UE4におけるLoadingと
GCのProfilingと最適化手法
https://www.slideshare.net/
EpicGamesJapan/
420-ue4loadinggcp...
ここまでのまとめ
これらの問題・対策は
全てのプラットフォームにおいて有効!
他にもヒッチの原因・対策はありますが…
負荷の削減・分散という考え方を大事にしましょう!
もちろん
プロファイリング をした上で!
本日のお品書き
ヒッチ対策 編
● そもそもヒッチってなに?
● 一般的なヒッチ対策について
● モバイル特有のヒッチ対策について
メモリ管理 編
● なぜモバイル開発において問題になるのか
● メモリに関するプロファイル方法について
最新情報...
モバイル特有のヒッチ対策…?
なぜモバイル特有の問題が起きるのか?
ハードウェア構成 と
グラフィックAPI が
他のプラットフォームと異なるから!
モバイル端末のハードウェア構成
SoC (System on a Chip) を採用
● CPU, GPU, メモリなどの各パーツをひとまとめにしたもの
● モバイル向けに省電力対応が入っている
モバイル端末のグラフィックAPI
Windowsなどで採用されている DirectX ではなく
モバイル向けのAPI ( OpenGL ES, Vulkan, Metal ) を採用
この違いにより何が起きるか…
それは…
Shader Compile 問題
メモリ転送速度 問題
Action RPGサンプルで検証
検証端末:Xperia Z5
● Snapdragon 810
● 2015年10月発売
https://youtu.be/ArHDo9v4rJg
CPUプロファイラ計測結果
50 ms
100 ms
150 ms
CPUプロファイラ計測結果
50 ms
100 ms
150 ms
Shader Compile 問題
メモリ転送速度 問題 が原因
強烈なヒッチが発生するため
このモバイル特有の問題への
対応は必須です
そして、
本日ご紹介する対応を入れると…
https://youtu.be/n_bIFnrlxu0
ヒッチが完全に無くなります!
これはもうやるしかないですよね…!?
やってやりましょう
モバイル特有のヒッチ対策について
● Shader Compile 問題
● メモリ転送速度 問題
Shader Compile問題について
● なぜShader Compile問題が発生するのか?
● PSO キャッシュについて
● 概要・流れ
● 使うために必要な操作・設定
● Tips
● PSOキャッシュによるPreCompile時間...
本講演では「Shaderを使えるようにする処理」のことを
Shader Compile とします
通常は Shader Compile は作業中だけですが…
モバイルの場合
実機でも Shader Compile が行われます!
ActionRPG における
敵キャラ の
初出現時 の負荷を計測
検証端末:Xperia Z5
( Snapdragon 810, 2015年10月発売 )
Action RPG における 敵キャラ初出現時の負荷
検証端末:Xperia Z5 ( 2015年10月発売 )
Action RPG における 敵キャラ出現時の負荷
検証端末:Xperia Z5 ( 2015年10月発売 )
Shader link Time : 471.014 ms
Shader Compile処理の一部 約15フレーム(30fpsの場...
なぜモバイルの場合
Shader Compileの問題が発生するのか?
実機上でShader Compileが問題になる理由
グラフィックスAPIの仕様
&
モバイル端末のCPU性能
Android, iOSで採用されているグラフィックスAPI
Android
● OpenGL ES
● Vulkan
iOS
● OpenGL ES
● Metal
OpenGL ES
開発会社・端末(ドライバ)毎に
実装・対応している機能が異なる状況
オフライン(事前)Shader Compileができず
実機上で行う必要がある
OpenGL ES
Shaderのソースコードを載せて、
実機上でShaderのCompile処理を実行
ソースコード 中間データ
Shader
Program
Compile
OpenGLShader() LinkProgram()
OpenGL ES
Shader Compile処理が完了すると
描画に必要な Shader Program がメモリ上に確保される
● 2回目以降は↑を使い回す
= 起動後に初めて使われる時のみShader Compileが走る
ソースコード...
Android, iOSで採用されているグラフィックスAPI
Android
● OpenGL ES
● Vulkan
iOS
● OpenGL ES
● Metal
時間などの関係で
Vulkanの話は しません!!!
時間などの関係で
Vulkanの話は しません!!!
少しします
Vulkanについて
ローレベルなグラフィックスAPI
OpenGL ESに比べてパフォーマンスが良い
Vulkanが抱えている課題
古い端末の場合、
ドライバが原因でパフォーマンスが出ない
UE4とVulkanについて
UE4.21リリースノートより
● OpenGL ES 3.1 との 機能互換性 が 100%
● OpenGL ES よりも
最大 20% 高速で実行できる可能性
GPU負荷に関しては少し上がる可能性あり
(鋭意...
Vulkanの採用を検討する基準についての参考情報
Vulkanによるパフォーマンス向上を見込める端末
● Snapdragon 845 以上
● Mali-G76 以上
FortniteにてVulkanを有効にしている端末 ( 2019年3月...
UE4のVulkan対応に関する詳細資料
● Vulkan! Powering AAA Experiences on Android
https://www.unrealengine.com/ja/events/unreal-fest-euro...
Android, iOSで採用されているグラフィックスAPI
Android
● OpenGL ES
● Vulkan
iOS
● OpenGL ES
● Metal
非推奨になったため
UE4.24で
サポート対象外に
Metal
ローレベルなグラフィックスAPI
OpenGL ESに比べてパフォーマンスが良い
Metal
オフラインShader Compileが可能
実機上でShader Compileしなくていい
Working with Metal: Overview
https://developer.apple.com/videos/play...
オフラインShader Compileをするには
● Mac上でビルドする
● Enable Remote Shader Compileを
有効にした状態でリモートビルド
(UE4.21, 4.22で不具合あり。4.23で修正)
Metalに関する負荷
Shaderの初回使用時に
Pipeline State Object の生成処理が必要
● GPUに渡す描画設定リスト
● OpenGL ESと同様に
2回目以降は生成されたものを使い回す
この生成処理がモバイルのCP...
Action RPG における 敵キャラ初出現時の負荷
検証端末:iPhone 7 ( 2016年9月発売 )
Action RPG における 敵キャラ初出現時の負荷
PipelineState time : 189.698 ms
検証端末:iPhone 7 ( 2016年9月発売 )
ざっくりまとめ
起動後 に 初めて 使われる Shaderの場合
Shader Compile 処理で生成されるデータが必要
● Shader Compile処理は非常に重い
生成されたデータは使い回せるため、
1度使用されたShaderを再度...
Shader Compileの負荷問題に
どう対策するか?
グラフィックスAPIの標準機能を活用する方法
Shader Compile結果をストレージに保存することで
2回目以降の起動でも再利用可能に
● Android : GL_OES_get_program_binary 拡張
● iOS : Me...
この問題を解決するために生まれた機能が…
Pipeline State Object (PSO) キャッシュ
( FShaderPipelineCache )
Shader Compile問題について
● なぜShader Compile問題が発生するのか?
● PSO キャッシュについて
● 概要・流れ
● 使うために必要な操作・設定
● Tips
● PSOキャッシュによるPreCompile時間...
PSOキャッシュはどういう機能?
事前に作成したShaderのリストを元に
Shader の PreCompile ( WarmUp ) を行う機能
PSOキャッシュが ない とき
Shader Compile !
ヒッチ
発生!
メモリ キャッシュ
PSOキャッシュが ある とき
PreCompile !
キャッシュ
PSOキャッシュ使用前
● CreateBoundShaderState time : 472 ms
● Shader link Time : 471 ms
PSOキャッシュ使用後
● CreateBoundShaderState time :...
PSOキャッシュの流れ
~ 事前準備からPreCompileまで ~
まずはイメージを掴むため
簡略した流れを紹介
PreCompileを行うための事前準備
実機上でゲームをプレイし
Shaderの組み合わせリスト を作成
を圧縮した を含めた
ユーザへの配布パッケージを作成
ユーザがプレイする際の実機上での処理
のリストにあるShaderに対して
Shader Compile。結果はメモリに保存
メモリに保存された結果を再利用
(Shader Compileをスキップ)
開発 環境
本番 環境
各処理の詳細について説明しますが
今は細かい部分は無視してダイジョブです
ふいんき(←なぜか変換できない)
を感じてください
1. Shaderの組み合わせリストの収集
後述の設定を行った後にCookして
Stable Shader情報リスト( *.scl.csv )を生成
● /Saved/Cooked/<PLATFORM>/<PROJECT>/Metadata/P...
scl.csvの中身
scl.csvの中身
Key Value
ClassNameAndObjectPath Material
/Engine/EngineMaterials/DefaultTextMaterialOpaque.DefaultTextMaterial...
2. PSOデータの収集
実機上でゲーム、又はテストレベルを動作させることで
Binary PSO ( *.rec.upipelinecache ) を生成
● /storage/emulated/0/UE4Game/<PROJECT>/Sav...
注意
Android上で生成したBinary PSOを
iOS向けビルドで使用することはできません
● Android, iOSでShaderのソースコードが異なるため
Binary PSO
for Android
Binary PSO
for...
3. PSOキャッシュのビルド
Binary PSO ( *.rec.upipelinecache ) と Stable Shader ( scl.csv ) から
Pipeline Metadata ( *.stablepc.csv )をビル...
stablepc.csv の中身
なるほどわからん
4. パッケージング・実行
/Build/<PLATFORM>/PipelineCache に
Pipeline Metadata ( *.stablepc.csv ) を入れた後に Packaging or Launch
● <PLATFOR...
5. PreCompile
アプリの起動直後、Binary PSO ( *.stable.upipelinecache ) を元に
Shader Compile処理を実行
● FShaderPipelineCache::Precompile()...
超ざっくりまとめ
1. 実機上でゲームをプレイして
シェーダの組み合わせリストを収集
2. そのリストを用いて、起動直後にShader Compile
結果をメモリにキャッシュとして保存
3. Shaderを実際に使うとき
そのキャッシュを再利...
PSOキャッシュを使う上で
必要となる作業・設定について
PSOキャッシュの使い方 公式ドキュメント
概要
https://docs.unrealengine.com/en-US/Engine/Rendering/PSOCaching/index.html
リファレンス
https://docs.un...
PSOキャッシュの使い方 ざっくり説明
1. r.ShaderPipelineCache.Enabled、
Share Material Shader Code, Shared Native Shader Librariesが有効の状態で
コマ...
検証を楽にするために batファイルを作りました
よく使う ADBコマンド を呼び出すエディタ拡張もあります
https://github.com/pafuhana1213/AdbCommandWidgetSample/tree/master/...
UE4.23 から
Stable Shader情報リスト( *.scl.csv ) を 出力するには
AndroidEngine.ini / iOSEngine.ini に 以下を追記する必要があります
● リストの構築・生成時間、ファイルサイ...
すこーし手間はかかりますが
Shader Compileによるヒッチ は PSOキャッシュで回避可能!
PSOキャッシュ最高!大好き!!結婚しよう!!!
…と終わればいいのですが、うまい話だけではなく
注意すべきことが幾つかあります
Shader Compile問題について
● なぜShader Compile問題が発生するのか?
● PSO キャッシュについて
● 概要・流れ
● 使うために必要な操作・設定
● Tips
● PSOキャッシュによるPreCompile時間...
PSOキャッシュによる
PreCompile時間について
PreCompileのタイミングについて
デフォルト設定の場合、
アプリ起動時( Engine の PreInit ) に PreCompile を開始
PreCompile時間の問題
PSOキャッシュによる PreCompile は
大量のShader Compile を 実行することになる
PreCompile中
PreCompile対象のShaderが増えると、
ゲームを遊べるまでの待ち時...
PreCompile時間の問題
Action RPGの場合:4.65 秒 (Xperia Z5 )
● LogRHI: Warning: FShaderPipelineCache completed 64 tasks in 4.41s
(4.6...
PreCompile 時間の問題への対策
● PreCompile処理を分散する
● PreCompile対象のShaderを制限する
● PreCompile対象のShaderを削減する
PreCompile 処理を分散する方法
起動直後にPreCompileを実行しないように
● r.ShaderPipelineCache.StartupMode 0
PreCompile処理の開始
● r.ShaderPipelineCach...
r.ShaderPipelineCache.SetBatchMode について
PreCompileの処理優先度を設定可能
Fast Mode (デフォルト)
● r.ShaderPipelineCache.SetBatchMode 2
● 暗...
おまけ r.ShaderPipelineCache.SetBatchMode は何を制御してるか
1フレームにおける
PreCompileするShader数 と PreCompile処理に費やす時間
PreCompileするShader数
● ...
PreCompileのタイミングをズラした際の注意点
PreCompileが未完了なShaderが使用されると
PSOキャッシュの恩恵を受けることができません!
PSOキャッシュを100%活かす為には
全PreCompileの完了を待つ処理が必...
Pause Background
PreCompile 完了
Background Fast
PreCompileの終了タイミング
FShaderPipelineCache :: GetPrecompilationCompleteDelegate()
または
FShaderPipelineCache :: NumPrecompilesR...
PreCompile時間の問題への対策
● PreCompileのタイミングをズラす
● PreCompile対象のShaderを制限する
● PreCompile対象のShaderを削減する
PreCompileのタイミングをズラす方法の問題点
タイミングをずらす・分散しただけなので、
ワーストケースでは数分レベルの待ち時間が発生
PreCompileするShader数が多いと
パッケージサイズ、メモリ使用量にも悪影響が…
PSOキャッシュ機能を使う上で大事なこと
(ほぼ)全てのShaderを
PSOキャッシュの対象にしようとしない
(ほぼ)全てのShaderを対象としない理由
先述の問題
● PreCompile処理時間、メモリ、パッケージサイズ
PSOキャッシュの事前準備コスト
● ゲームを最初から最後まで
様々な行動をしながらプレイする必要がある
● しかも、2つのO...
どんなShaderを
PSOキャッシュの対象にすればいいのか?
Shader Compileが必要なタイミング
Shaderが初めて使われるとき
オブジェクトを動的に生成したとき
ヒッチが起きると遊びの邪魔になりストレスに
レベルをロードしたとき
暗転・ローディング画面を表示中なことが多いため
ヒッチが起き...
PSOキャッシュ対象のShaderを絞るためには…
対象のShaderを使用するオブジェクトのみを配置した
PSOキャッシュ収集用レベルを構築・使用!
PSOキャッシュ収集用レベルの例
Qiita : UE4 Shader Pipeline Cache に
乗っていないShaderーを調査する
(@Takezoh さん )
イカロスM ポストモーテム講演
EditorScripting で PSOキャッシュ収集用レベルを自動生成
PreCompile時間の問題への対策
● PreCompileのタイミングをズラす
● PreCompile対象のShaderを制限する
● PreCompile対象のShaderを削減する
マテリアルの管理に注意しないと
Shaderの数は簡単に膨れ上がります
数を抑えることで
PreCompileの対象を減らせます
Shaderの組み合わせリスト
Shaderの組み合わせリスト
Shaderの組み合わせを減らすと、Shaderの数は減る
Shaderの組み合わせリスト
Shaderの組み合わせを減らすと、Shaderの数は減る
(逆もまた然り)
この部分を減らすためには…
Shaderの数を減らす / 増やさないためには… その1
Material の Usage にて 不要な項目は必ず無効に
● Usage毎に別Shaderが生成されるため
この部分を減らすためには…
Shaderの数を減らす / 増やさないためには… その2
( Mobile ) Shader Permutation Reduction を活用
● プロジェクトで使用しない機能をOFFにすることで
不要なShaderの生成を防ぐ機能
詳細はこちら
https://www.slideshare.net/EpicGamesJapan/epic-games-japan-ue4dd
Shaderの数を減らす / 増やさないためには… その3
不要な設定・アセットが
パッケージに含まれないようにする
モバイル以外の
プラットフォームも対応する際に重要
詳細はこちら
https://www.slideshare.net/EpicGamesJapan/ue4mobilestudy
PreCompile時間の問題への対策
● PreCompileのタイミングをズラす
● 起動直後ではなく、ゲームフローに適したタイミングに
● PreCompile対象のShaderを制限する
● 動的に生成するものなど、ヒッチが目立つものを...
Shader Compile問題について
● なぜShader Compile問題が発生するのか?
● PSO キャッシュについて
● 概要・流れ
● 使うために必要な操作・設定
● Tips
● PSOキャッシュによるPreCompile時間...
ProgramBinaryCache
( Android OpenGL ES専用 )
OpenGL ES の PreCompileの問題点
OpenGL ES には Shader Compile結果を
次回起動以降に再利用する機能が標準では用意されていません
起動の度に、ソースコードからの
Shader Compile という高...
ProgramBinaryCacheとは?
PSOキャッシュによるPreCompile結果を保存し
次回起動時に再利用することでPreCompileを短縮する機能
r.ProgramBinaryCache.Enable
(デフォルト:有効)
PreCompile時間短縮効果
ProgramBinaryCache:無効
● 1回目:4.41 s
● 2回目:2.03 s
ProgramBinaryCache:有効
● 1回目:4.36 s
● 2回目:0.54 s
とあるプロジェクト...
ProgramBinaryCache 初回起動時
PreCompileの過程で生成された
Program Binary (glProgramBinary) を ストレージに保存
● /storage/emulated/0/Android/dat...
ProgramBinaryCache 2回目以降
PreCompile時に ストレージ内のProgram Binary から
Shader Program を 生成
● ソースコードからの変換に比べて格段に高速
● FOpenGLProgram...
PreCompile
開始
Program
Binary は
ある?
ソースコード
から Compile
Shader Program
生成
Program
Binary
保存
Program Binary から
Shader Program ...
補足
● 注意:PSOキャッシュ使用前提の機能です
● r.OpenGL.StoreCompressedProgramBinaries で更に圧縮可能
ただし解凍コストが発生
● UE4.20以前は PSOキャッシュ関係なく
バイナリを保存する...
ProgramBinaryCacheには
PSOキャッシュによる初回PreCompile後に
アプリを再起動する機能があります
初回PreCompile後にアプリを再起動する機能
r.ProgramBinaryCache.RestartAndroidAfterPrecompile
(デフォルト:有効)
https://youtu.be/OAkKAqz709k
なんで再起動するん?
ソースコードからのCompile過程で発生した
余分なメモリ消費をリセットするため
PreCompile
開始
Program
Binary は
ある?
ソースコード
から Compile
Shader Program
生...
注意
デフォルトの場合、ユーザから見ると突然再起動が走ることに
再起動することを通知する画面があると安心
● 再起動処理を行っている
FOpenGLProgramBinaryCache::
OnShaderPipelineCachePrecom...
Shader Compile問題について
● なぜShader Compile問題が発生するのか?
● PSO キャッシュについて
● 概要・流れ
● 使うために必要な操作・設定
● Tips
● PSOキャッシュによるPreCompile時間...
ProgramLRUCache
( Android OpenGL ES専用 )
とあるプロジェクトで発生した問題
Adreno 端末:
● Program Binary 40MB から生成される
Shader Program が 400MB以上 に
Mali 端末:
● Shader Program の
メモリ使用量が一定...
ProgramLRUCache
メモリ使用量、又はShader Program数が一定値を超えた際に
使用頻度が低い Shader Program をメモリから破棄する機能
● LRU = Least Recently Used
r.OpenG...
破棄を開始する基準について
r.OpenGL.ProgramLRUBinarySize
● メモリ上に格納する Shader Program の 最大バイト数
● デフォルト値:35*1024*1024
r.OpenGL.ProgramLRUC...
メモリ
メモリ
Shader Compile !
メモリShader
Program
Shader Compile !
Shader
Program
Shader Compile !
Shader
Program
Shader
Program
Shader Programによる
メモリ使用量が増大
Shader
Program
Shader
Program
Shader
Program
Program
Binary
使用頻度の低い Shader Program から
再生成用のProgram Binaryを作成
Shader
Program
Shader
Program
Program
Binary
使用頻度の低い Shader Programを
メモリから破棄
Shader
Program
Shader
Program
Shader
Program
Program
Binary
Shader Programによる
メモリ使用量が減少!
Shader
Program
Shader
Program
Program
Binary
破棄したShader Programが
再度必要になると…
Shader
Program
Shader
Program
Shader
Program
Program
Binary
Program Binaryから再生成するので
Shader Compileは走らない
Shader
Program
Shader
Program
Shader
Program
再生成後、
Program Binaryをメモリから破棄
Program
Binary
ProgramLRUCache のオプション
r.OpenGL.ProgramLRUKeepBinaryResident
● 再生成用のProgram Binary を
メモリ上に保持し続けるか否かの制御
● デフォルト:無効
ProgramLRUKeepBinaryResident が
有効の場合
r.OpenGL.ProgramLRUKeepBinaryResident:有効の場合
使用頻度の低いShader Program を
メモリから破棄するところまでは無効時と同じ
Program
Binary
Shader
Program
Sh...
r.OpenGL.ProgramLRUKeepBinaryResident:有効の場合
Shader Programを再生成した後も
メモリ上に Program Binaryを保持し続けることが異なる点
Program
Binary
Shade...
r.OpenGL.ProgramLRUKeepBinaryResident:有効の場合
Shader Programを再生成した後も
メモリ上に Program Binaryを保持し続けることが異なる点
Program
Binary
Shade...
パフォーマンス : 無効 < 有効
メモリ使用量 : 無効 > 有効
ここまでのまとめ
ProgramBinaryCache
● Shader Compile結果をストレージに保存することで
2回目以降の起動時のPreCompile時間を短縮する機能
ProgramLRUCache
● Shader Compil...
Shader Compile編のまとめ
● モバイルの場合、実機上でShader Compileが走るため
対策を入れていない場合は強烈なヒッチが発生
● PSOキャッシュを使って PreCompile することで
ユーザにストレスを与えるヒッ...
おまけ
rhi.Metal.CacheShaderPipelines
● Pipeline State Object(PSO)をメモリ上に保持し続けるか否か
● 有効(デフォルト):保持し続ける
● 無効:
すべてのRHI参照が解放されると、P...
Part 2へ
  そう、UE4ならね。あなたのモバイルゲームをより快適にする沢山の冴えたやり方について Part 1 <Shader Compile, PSO Cache編>
  そう、UE4ならね。あなたのモバイルゲームをより快適にする沢山の冴えたやり方について Part 1 <Shader Compile, PSO Cache編>
  そう、UE4ならね。あなたのモバイルゲームをより快適にする沢山の冴えたやり方について Part 1 <Shader Compile, PSO Cache編>
  そう、UE4ならね。あなたのモバイルゲームをより快適にする沢山の冴えたやり方について Part 1 <Shader Compile, PSO Cache編>
  そう、UE4ならね。あなたのモバイルゲームをより快適にする沢山の冴えたやり方について Part 1 <Shader Compile, PSO Cache編>
  そう、UE4ならね。あなたのモバイルゲームをより快適にする沢山の冴えたやり方について Part 1 <Shader Compile, PSO Cache編>
  そう、UE4ならね。あなたのモバイルゲームをより快適にする沢山の冴えたやり方について Part 1 <Shader Compile, PSO Cache編>
  そう、UE4ならね。あなたのモバイルゲームをより快適にする沢山の冴えたやり方について Part 1 <Shader Compile, PSO Cache編>
  そう、UE4ならね。あなたのモバイルゲームをより快適にする沢山の冴えたやり方について Part 1 <Shader Compile, PSO Cache編>
  そう、UE4ならね。あなたのモバイルゲームをより快適にする沢山の冴えたやり方について Part 1 <Shader Compile, PSO Cache編>
Upcoming SlideShare
Loading in …5
×

そう、UE4ならね。あなたのモバイルゲームをより快適にする沢山の冴えたやり方について Part 1 <Shader Compile, PSO Cache編>

7,821 views

Published on

補足:LRUキャッシュの導入を検討する際は OpenGL.UseEmulatedUBsの有効化も合わせてご検討ください。

講演動画:https://youtu.be/A_l65FlY25I
Part 2:https://www.slideshare.net/EpicGamesJapan/ue4-festeast2019-ue4mobilepart2-179705328

2019年10月6日に行われた「UNREAL FEST EAST 2019」で登壇した際に使用した資料です。
●公式サイト
https://unrealengine.jp/unrealfest/
===
シェーダコンパイルによるカクツキなどモバイルゲーム開発特有の問題は数多くあり、それらはユーザのストレスに繋がる可能性があります。UE4はそういった問題に対しての機能を持っていますが、用法・用量を守って正しく使わないと別の問題を引き起こしてしまいます。そこで本講演ではそれらの機能の使い方、注意点などについて解説します(他のプラットフォーム開発でも役立つ内容にする予定です)。あ、今年は1人講演です。

Published in: Engineering
  • Be the first to comment

そう、UE4ならね。あなたのモバイルゲームをより快適にする沢山の冴えたやり方について Part 1 <Shader Compile, PSO Cache編>

  1. 1. そう、UE4ならね。 あなたのモバイルゲームをより快適にする 沢山の冴えたやり方について Part1 Epic Games Japan Support Engineer 岡田和也
  2. 2. 本日のハッシュタグ #ue4fest スライドは近日公開予定 しました
  3. 3. 本スライド、300ページ超えだったせいなのか Slideshareへのアップに失敗しました /(^o^)\ そのため、Part1, 2に分割しています Part 2のURLに関しましては Slideshareの説明文をご確認ください
  4. 4. 自己紹介 Epic Games Japan サポートエンジニア 岡田 和也 Twitter: おかず ( @pafuhana1213 ) ライセンシのサポート業務や講演が主なお仕事 最近モバイル担当してます
  5. 5. 国内のUE4モバイルタイトル 増えてきました…!
  6. 6. 国内のUE4製モバイルタイトル
  7. 7. New! VARIOUS DAYLIFE(バリアスデイライフ) Apple Arcade にて 絶賛配信中!
  8. 8. UE4モバイルタイトルに携わる人向けに より実践的な話をせねば…!
  9. 9. これまでのUE4モバイルに関する講演を 振り返ってみると…
  10. 10. モバイル関連の機能・最新情報紹介 最新モバイルゲームの実例からみるUE4のモバイル向け機能・Tipsを 全部まるっとご紹介! + UE4.18 モバイル最新情報の紹介 https://www.slideshare.net/EpicGamesJapan/cedeckyushu-2017-ue4tips UE4のモバイル向け機能や最新情報などを改めて紹介!2019 https://www.slideshare.net/EpicGamesJapan/ue4mobilestudy
  11. 11. コンテンツアップデートについて UE4のモバイル開発におけるコンテンツアップデートの話 - Chunk IDとの激闘編 – https://www.slideshare.net/EpicGamesJapan/ue4-chunk-id 徹底解説!UE4を使ったモバイルゲーム開発における コンテンツアップデートの極意! https://www.slideshare.net/EpicGamesJapan/ue4-95204920
  12. 12. 某ブログにて 【UE4 & Android】実機デバッグ実行中のログ確認方法について http://pafuhana1213.hatenablog.com/entry/2019/02/20/013340 UE4 & iOS開発時の実機デバッグ・プロファイリング方法 まとめ 2018 http://pafuhana1213.hatenablog.com/entry/2018/12/13/031332
  13. 13. 振り返ってみると… モバイル開発において避けることができない モバイル特有のヒッチ メモリ問題 についてガッツリ話したことがない! ユーザのストレス・継続率に 大きく影響する重要な問題
  14. 14. これらの問題に対する対策が 不十分な場合、様々な問題が発生します
  15. 15. たとえば… ● プレイ中のカクツキ ● 長時間ロード ● 発熱からのパフォーマンス低下 ● 猛烈に減る電池 ● 突然のクラッシュ ● などなどなど…
  16. 16. やばい
  17. 17. 早い段階から対策を入れることで ゲームをより快適にしていきましょう! (普段の開発も快適に!)
  18. 18. 本日のお品書き ヒッチ対策 編 ● そもそもヒッチってなに? ● 一般的なヒッチ対策について ● モバイル特有のヒッチ対策について メモリ管理 編 ● なぜモバイル開発において問題になるのか ● メモリに関するプロファイル方法について 最新情報 編 ● UE4.23 で入った モバイル関連の便利機能・最適化について
  19. 19. そもそもヒッチってなに?
  20. 20. ヒッチ( Hitch )とは? ● 引っかける ● (くいなどに)つなぐ ● (…を)ぐいと動かす ● (ヒッチハイクで)させてもらう ● ヒッチハイクで行く Weblio英和辞書 より
  21. 21. いわゆる、カクつき
  22. 22. ゲームにおけるカクつき それまで滑らかに動いていたのが 急にカクついたり、一定時間画面が止まったり… https://youtu.be/6oR9GWGgBZY
  23. 23. イライラがすごい
  24. 24. 海外だとHitchと表現することが多いため 本講演もそれに倣います Google先生に聞くときもこれを意識するのオススメ!
  25. 25. ヒッチは なぜ / いつ 起きる? あるフレーム(タイミング)で 非常に負荷が重い処理 、 または 大量の処理 が実行されたときに発生
  26. 26. ヒッチは なぜ / いつ 起きる? あるフレーム(タイミング)で 非常に負荷が重い処理 、 または 大量の処理 が実行されたときに発生
  27. 27. ヒッチを回避するには どうすればいいのか?
  28. 28. ヒッチ対策の基本的な方針 その1 負荷 を 削減
  29. 29. ヒッチ対策の基本的な方針 その2 処理の数 を 削減
  30. 30. ヒッチ対策の基本的な方針 その3 大量の処理 を 複数フレーム に 分散
  31. 31. ヒッチ対策の基本的な方針 その3.5 大量の処理 を 複数フレーム に 分散
  32. 32. ヒッチ対策の基本的な方針 その4 重い処理 を 複数フレーム に 分散
  33. 33. ここまでのまとめ ヒッチを回避するには どうすればいいのか? 負荷を 削減 ・分散する
  34. 34. 本日のお品書き ヒッチ対策 編 ● そもそもヒッチってなに? ● 一般的なヒッチ対策について ● モバイル特有のヒッチ対策について メモリ管理 編 ● なぜモバイル開発において問題になるのか ● メモリに関するプロファイル方法について 最新情報 編 ● UE4.23 で入った モバイル関連の便利機能・最適化について
  35. 35. ヒッチが起きやすいタイミング ● アセット・レベルのロード ● オブジェクトの生成 ● ガベージコレクション(GC)
  36. 36. アセットのロード数を 削減 アセット間の参照関係を整理 ● 直接参照の場合 連鎖的にロード処理が走るため Unreal Fest East 2018 Nintendo Switch『OCTOPATH TRAVELER』は こうして作られた https://www.slideshare.net/EpicGamesJapan/ nintendo-switchoctopath-traveler
  37. 37. レベルを複数のサブレベルに分割 ● 必要に応じてロード・アンロード ● ロードタイミングの分散 アセットのロード数を 削減・分散
  38. 38. アセットのロード数を 分散 実際に使われる前に事前ロード(前読み) Qiita:Asset Managerのアセットの非同期ロード機能について
  39. 39. ヒッチが起きやすいタイミング ● アセット・レベルのロード ● オブジェクトの生成 ● ガベージコレクション(GC)
  40. 40. 動的にActorを生成すると… アセットのロード後に各初期化処理が走る ● Construction Script, Begin Playなど BP_Bullet
  41. 41. オブジェクトの生成処理を 削減・分散 ● Construction Script, Begin Play における処理の削減・分散 ● 生成タイミング自体を分散 ● オブジェクトプール(常駐・使い回し)で分散
  42. 42. ヒッチが起きやすいタイミング ● アセット・レベルのロード ● オブジェクトの生成 ● ガベージコレクション(GC)
  43. 43. GCの対策 この資料読んで!以上! [4.20版] UE4におけるLoadingと GCのProfilingと最適化手法 https://www.slideshare.net/ EpicGamesJapan/ 420-ue4loadinggcprofiling-108367408
  44. 44. ここまでのまとめ これらの問題・対策は 全てのプラットフォームにおいて有効! 他にもヒッチの原因・対策はありますが… 負荷の削減・分散という考え方を大事にしましょう! もちろん プロファイリング をした上で!
  45. 45. 本日のお品書き ヒッチ対策 編 ● そもそもヒッチってなに? ● 一般的なヒッチ対策について ● モバイル特有のヒッチ対策について メモリ管理 編 ● なぜモバイル開発において問題になるのか ● メモリに関するプロファイル方法について 最新情報 編 ● UE4.23 で入った モバイル関連の便利機能・最適化について
  46. 46. モバイル特有のヒッチ対策…?
  47. 47. なぜモバイル特有の問題が起きるのか? ハードウェア構成 と グラフィックAPI が 他のプラットフォームと異なるから!
  48. 48. モバイル端末のハードウェア構成 SoC (System on a Chip) を採用 ● CPU, GPU, メモリなどの各パーツをひとまとめにしたもの ● モバイル向けに省電力対応が入っている
  49. 49. モバイル端末のグラフィックAPI Windowsなどで採用されている DirectX ではなく モバイル向けのAPI ( OpenGL ES, Vulkan, Metal ) を採用
  50. 50. この違いにより何が起きるか… それは… Shader Compile 問題 メモリ転送速度 問題
  51. 51. Action RPGサンプルで検証 検証端末:Xperia Z5 ● Snapdragon 810 ● 2015年10月発売
  52. 52. https://youtu.be/ArHDo9v4rJg
  53. 53. CPUプロファイラ計測結果 50 ms 100 ms 150 ms
  54. 54. CPUプロファイラ計測結果 50 ms 100 ms 150 ms Shader Compile 問題 メモリ転送速度 問題 が原因
  55. 55. 強烈なヒッチが発生するため このモバイル特有の問題への 対応は必須です
  56. 56. そして、 本日ご紹介する対応を入れると…
  57. 57. https://youtu.be/n_bIFnrlxu0
  58. 58. ヒッチが完全に無くなります! これはもうやるしかないですよね…!?
  59. 59. やってやりましょう
  60. 60. モバイル特有のヒッチ対策について ● Shader Compile 問題 ● メモリ転送速度 問題
  61. 61. Shader Compile問題について ● なぜShader Compile問題が発生するのか? ● PSO キャッシュについて ● 概要・流れ ● 使うために必要な操作・設定 ● Tips ● PSOキャッシュによるPreCompile時間について ● ProgramBinaryCache ● ProgramLRUCache
  62. 62. 本講演では「Shaderを使えるようにする処理」のことを Shader Compile とします 通常は Shader Compile は作業中だけですが… モバイルの場合 実機でも Shader Compile が行われます!
  63. 63. ActionRPG における 敵キャラ の 初出現時 の負荷を計測 検証端末:Xperia Z5 ( Snapdragon 810, 2015年10月発売 )
  64. 64. Action RPG における 敵キャラ初出現時の負荷 検証端末:Xperia Z5 ( 2015年10月発売 )
  65. 65. Action RPG における 敵キャラ出現時の負荷 検証端末:Xperia Z5 ( 2015年10月発売 ) Shader link Time : 471.014 ms Shader Compile処理の一部 約15フレーム(30fpsの場合)
  66. 66. なぜモバイルの場合 Shader Compileの問題が発生するのか?
  67. 67. 実機上でShader Compileが問題になる理由 グラフィックスAPIの仕様 & モバイル端末のCPU性能
  68. 68. Android, iOSで採用されているグラフィックスAPI Android ● OpenGL ES ● Vulkan iOS ● OpenGL ES ● Metal
  69. 69. OpenGL ES 開発会社・端末(ドライバ)毎に 実装・対応している機能が異なる状況 オフライン(事前)Shader Compileができず 実機上で行う必要がある
  70. 70. OpenGL ES Shaderのソースコードを載せて、 実機上でShaderのCompile処理を実行 ソースコード 中間データ Shader Program Compile OpenGLShader() LinkProgram()
  71. 71. OpenGL ES Shader Compile処理が完了すると 描画に必要な Shader Program がメモリ上に確保される ● 2回目以降は↑を使い回す = 起動後に初めて使われる時のみShader Compileが走る ソースコード 中間データ Shader Program Compile OpenGLShader() LinkProgram()
  72. 72. Android, iOSで採用されているグラフィックスAPI Android ● OpenGL ES ● Vulkan iOS ● OpenGL ES ● Metal
  73. 73. 時間などの関係で Vulkanの話は しません!!!
  74. 74. 時間などの関係で Vulkanの話は しません!!! 少しします
  75. 75. Vulkanについて ローレベルなグラフィックスAPI OpenGL ESに比べてパフォーマンスが良い Vulkanが抱えている課題 古い端末の場合、 ドライバが原因でパフォーマンスが出ない
  76. 76. UE4とVulkanについて UE4.21リリースノートより ● OpenGL ES 3.1 との 機能互換性 が 100% ● OpenGL ES よりも 最大 20% 高速で実行できる可能性 GPU負荷に関しては少し上がる可能性あり (鋭意対応中)
  77. 77. Vulkanの採用を検討する基準についての参考情報 Vulkanによるパフォーマンス向上を見込める端末 ● Snapdragon 845 以上 ● Mali-G76 以上 FortniteにてVulkanを有効にしている端末 ( 2019年3月時点 ) ● Galaxy S9 ( Adreno ) ● Galaxy Note 9 ( Adreno, Mali ) ● Galaxy S10 ( Adreno, Mali )
  78. 78. UE4のVulkan対応に関する詳細資料 ● Vulkan! Powering AAA Experiences on Android https://www.unrealengine.com/ja/events/unreal-fest-europe-2019/vulkan-powering-aaa- experiences-on-android?lang=ja
  79. 79. Android, iOSで採用されているグラフィックスAPI Android ● OpenGL ES ● Vulkan iOS ● OpenGL ES ● Metal 非推奨になったため UE4.24で サポート対象外に
  80. 80. Metal ローレベルなグラフィックスAPI OpenGL ESに比べてパフォーマンスが良い
  81. 81. Metal オフラインShader Compileが可能 実機上でShader Compileしなくていい Working with Metal: Overview https://developer.apple.com/videos/play/ wwdc2014/603/
  82. 82. オフラインShader Compileをするには ● Mac上でビルドする ● Enable Remote Shader Compileを 有効にした状態でリモートビルド (UE4.21, 4.22で不具合あり。4.23で修正)
  83. 83. Metalに関する負荷 Shaderの初回使用時に Pipeline State Object の生成処理が必要 ● GPUに渡す描画設定リスト ● OpenGL ESと同様に 2回目以降は生成されたものを使い回す この生成処理がモバイルのCPU性能では 非常に重く…ヒッチの原因に… https://software.intel.com/en-us/blogs/2014/07/23/direct3d- 12-overview-part-2-pipeline-state-object
  84. 84. Action RPG における 敵キャラ初出現時の負荷 検証端末:iPhone 7 ( 2016年9月発売 )
  85. 85. Action RPG における 敵キャラ初出現時の負荷 PipelineState time : 189.698 ms 検証端末:iPhone 7 ( 2016年9月発売 )
  86. 86. ざっくりまとめ 起動後 に 初めて 使われる Shaderの場合 Shader Compile 処理で生成されるデータが必要 ● Shader Compile処理は非常に重い 生成されたデータは使い回せるため、 1度使用されたShaderを再度使うときは Shader Compile処理が走らない OpenGL ESの場合は 生成されたデータはアプリ終了時に消去されるため 2回目以降の起動でも、初回使用時はShader Compileが必要になる
  87. 87. Shader Compileの負荷問題に どう対策するか?
  88. 88. グラフィックスAPIの標準機能を活用する方法 Shader Compile結果をストレージに保存することで 2回目以降の起動でも再利用可能に ● Android : GL_OES_get_program_binary 拡張 ● iOS : Metalの標準機能 問題 ● 初回起動 かつ 初回使用時のヒッチが解決できない ● Androidの場合、メモリ使用量が膨大になる
  89. 89. この問題を解決するために生まれた機能が… Pipeline State Object (PSO) キャッシュ ( FShaderPipelineCache )
  90. 90. Shader Compile問題について ● なぜShader Compile問題が発生するのか? ● PSO キャッシュについて ● 概要・流れ ● 使うために必要な操作・設定 ● Tips ● PSOキャッシュによるPreCompile時間について ● ProgramBinaryCache ● ProgramLRUCache
  91. 91. PSOキャッシュはどういう機能? 事前に作成したShaderのリストを元に Shader の PreCompile ( WarmUp ) を行う機能
  92. 92. PSOキャッシュが ない とき Shader Compile ! ヒッチ 発生! メモリ キャッシュ
  93. 93. PSOキャッシュが ある とき PreCompile ! キャッシュ
  94. 94. PSOキャッシュ使用前 ● CreateBoundShaderState time : 472 ms ● Shader link Time : 471 ms PSOキャッシュ使用後 ● CreateBoundShaderState time : 0.6 ms ● Shader link Time : 0 ms 470ms あった負荷が 1ms以下に!
  95. 95. PSOキャッシュの流れ ~ 事前準備からPreCompileまで ~
  96. 96. まずはイメージを掴むため 簡略した流れを紹介
  97. 97. PreCompileを行うための事前準備 実機上でゲームをプレイし Shaderの組み合わせリスト を作成 を圧縮した を含めた ユーザへの配布パッケージを作成
  98. 98. ユーザがプレイする際の実機上での処理 のリストにあるShaderに対して Shader Compile。結果はメモリに保存 メモリに保存された結果を再利用 (Shader Compileをスキップ)
  99. 99. 開発 環境 本番 環境
  100. 100. 各処理の詳細について説明しますが 今は細かい部分は無視してダイジョブです ふいんき(←なぜか変換できない) を感じてください
  101. 101. 1. Shaderの組み合わせリストの収集 後述の設定を行った後にCookして Stable Shader情報リスト( *.scl.csv )を生成 ● /Saved/Cooked/<PLATFORM>/<PROJECT>/Metadata/PipelineCaches
  102. 102. scl.csvの中身
  103. 103. scl.csvの中身 Key Value ClassNameAndObjectPath Material /Engine/EngineMaterials/DefaultTextMaterialOpaque.DefaultTextMaterialOpaq ue ShaderType TMobileBasePassPSFMobileMovableDirectionalLightAndSHIndirectPolicyIN T32_MAXHDRLinear64Skylight ShaderClass MeshMaterial MaterialDomain MD_Surface FeatureLevel ES3_1 QualityLevel High TargetFrequency SF_Pixel TargetPlatform GLSL_ES3_1_ANDROID VFType FLocalVertexFactory Permutation Perm_0 OutputHash 8970309F7B3BF9D92B463D067104580E5AAA3519
  104. 104. 2. PSOデータの収集 実機上でゲーム、又はテストレベルを動作させることで Binary PSO ( *.rec.upipelinecache ) を生成 ● /storage/emulated/0/UE4Game/<PROJECT>/Saved/CollectedPSOs Stable Shader Binary PSO
  105. 105. 注意 Android上で生成したBinary PSOを iOS向けビルドで使用することはできません ● Android, iOSでShaderのソースコードが異なるため Binary PSO for Android Binary PSO for iOS
  106. 106. 3. PSOキャッシュのビルド Binary PSO ( *.rec.upipelinecache ) と Stable Shader ( scl.csv ) から Pipeline Metadata ( *.stablepc.csv )をビルド Stable Shader Binary PSO Pipeline Metadata
  107. 107. stablepc.csv の中身 なるほどわからん
  108. 108. 4. パッケージング・実行 /Build/<PLATFORM>/PipelineCache に Pipeline Metadata ( *.stablepc.csv ) を入れた後に Packaging or Launch ● <PLATFORM> = Android or iOS ● Cook 時に Binary PSO ( *.stable.upipelinecache ) に変換 Pipeline Metadata Binary PSO バイナリ形式に圧縮 不要な情報を削除
  109. 109. 5. PreCompile アプリの起動直後、Binary PSO ( *.stable.upipelinecache ) を元に Shader Compile処理を実行 ● FShaderPipelineCache::Precompile() Shader Program Create~Shader SetGraphicsPipelineState
  110. 110. 超ざっくりまとめ 1. 実機上でゲームをプレイして シェーダの組み合わせリストを収集 2. そのリストを用いて、起動直後にShader Compile 結果をメモリにキャッシュとして保存 3. Shaderを実際に使うとき そのキャッシュを再利用することでヒッチを回避 開発 環境 本番 環境
  111. 111. PSOキャッシュを使う上で 必要となる作業・設定について
  112. 112. PSOキャッシュの使い方 公式ドキュメント 概要 https://docs.unrealengine.com/en-US/Engine/Rendering/PSOCaching/index.html リファレンス https://docs.unrealengine.com/ja/Engine/Rendering/PSOCaching/PSOReference/index.html FAQ https://docs.unrealengine.com/ja/Engine/Rendering/PSOCaching/FAQ/index.html 1. PSO キャッシングの有効化とビルド https://docs.unrealengine.com/ja/Engine/Rendering/PSOCaching/EnablingBuildingPSOCaching/index.html 2. PSO データの収集 https://docs.unrealengine.com/ja/Engine/Rendering/PSOCaching/GatheringPSOData/index.html 3. PSO キャッシュのビルド https://docs.unrealengine.com/ja/Engine/Rendering/PSOCaching/BuildingPSOCache/index.html 4. PSO キャッシングを使用した UE4 プロジェクトのビルド https://docs.unrealengine.com/ja/Engine/Rendering/PSOCaching/BuildingUE4ProjectWithPSOCaching/index.html 5. PSO キャッシング データのコンパイルと使用 https://docs.unrealengine.com/ja/Engine/Rendering/PSOCaching/CompilingUsingPSOCachingData/index.html
  113. 113. PSOキャッシュの使い方 ざっくり説明 1. r.ShaderPipelineCache.Enabled、 Share Material Shader Code, Shared Native Shader Librariesが有効の状態で コマンドラインパラメータに -logPSO を追加したパッケージを作成し、 一通りゲームを遊ぶ(又は、PSOキャッシュ収集用レベルを開く) 2. 1の過程で生成された *.scl.csv と *.rec.upipelinecache から *.stablepc.csv を生成 3. *.stablepc.csv を含むパッケージを作成 4. アプリ起動後にShaderをPreCompile PreCompile完了後、PSOキャッシュデータの対象となるShaderは そのデータを再利用するため、Shader Compileが不要に
  114. 114. 検証を楽にするために batファイルを作りました よく使う ADBコマンド を呼び出すエディタ拡張もあります https://github.com/pafuhana1213/AdbCommandWidgetSample/tree/master/Plugi ns/AdbCommandEditorWidget/Bat iOS向けは…いつか…
  115. 115. UE4.23 から Stable Shader情報リスト( *.scl.csv ) を 出力するには AndroidEngine.ini / iOSEngine.ini に 以下を追記する必要があります ● リストの構築・生成時間、ファイルサイズを改善するため [DevOptions.Shaders] NeedsShaderStableKeys = true
  116. 116. すこーし手間はかかりますが Shader Compileによるヒッチ は PSOキャッシュで回避可能! PSOキャッシュ最高!大好き!!結婚しよう!!! …と終わればいいのですが、うまい話だけではなく 注意すべきことが幾つかあります
  117. 117. Shader Compile問題について ● なぜShader Compile問題が発生するのか? ● PSO キャッシュについて ● 概要・流れ ● 使うために必要な操作・設定 ● Tips ● PSOキャッシュによるPreCompile時間について ● ProgramBinaryCache ● ProgramLRUCache
  118. 118. PSOキャッシュによる PreCompile時間について
  119. 119. PreCompileのタイミングについて デフォルト設定の場合、 アプリ起動時( Engine の PreInit ) に PreCompile を開始
  120. 120. PreCompile時間の問題 PSOキャッシュによる PreCompile は 大量のShader Compile を 実行することになる PreCompile中 PreCompile対象のShaderが増えると、 ゲームを遊べるまでの待ち時間も増える
  121. 121. PreCompile時間の問題 Action RPGの場合:4.65 秒 (Xperia Z5 ) ● LogRHI: Warning: FShaderPipelineCache completed 64 tasks in 4.41s (4.65s wall time since intial open). 一定規模以上のプロジェクトの場合 数分レベルの待ち時間が発生することも…
  122. 122. PreCompile 時間の問題への対策 ● PreCompile処理を分散する ● PreCompile対象のShaderを制限する ● PreCompile対象のShaderを削減する
  123. 123. PreCompile 処理を分散する方法 起動直後にPreCompileを実行しないように ● r.ShaderPipelineCache.StartupMode 0 PreCompile処理の開始 ● r.ShaderPipelineCache.SetBatchMode 1 or 2 PreCompile処理の中断 ● r.ShaderPipelineCache.SetBatchMode 0
  124. 124. r.ShaderPipelineCache.SetBatchMode について PreCompileの処理優先度を設定可能 Fast Mode (デフォルト) ● r.ShaderPipelineCache.SetBatchMode 2 ● 暗転中やローディング画面中に、全力でPreCompile Background Mode ● r.ShaderPipelineCache.SetBatchMode 1 ● ゲームプレイ中の裏で、少しずつPreCompile
  125. 125. おまけ r.ShaderPipelineCache.SetBatchMode は何を制御してるか 1フレームにおける PreCompileするShader数 と PreCompile処理に費やす時間 PreCompileするShader数 ● r.ShaderPipelineCache.BatchSize ● r.ShaderPipelineCache.BackgroundBatchSize PreCompile処理に費やす時間 ● r.ShaderPipelineCache.BatchTime ● r.ShaderPipelineCache.BackgroundBatchTime
  126. 126. PreCompileのタイミングをズラした際の注意点 PreCompileが未完了なShaderが使用されると PSOキャッシュの恩恵を受けることができません! PSOキャッシュを100%活かす為には 全PreCompileの完了を待つ処理が必要!
  127. 127. Pause Background
  128. 128. PreCompile 完了 Background Fast
  129. 129. PreCompileの終了タイミング FShaderPipelineCache :: GetPrecompilationCompleteDelegate() または FShaderPipelineCache :: NumPrecompilesRemaining()
  130. 130. PreCompile時間の問題への対策 ● PreCompileのタイミングをズラす ● PreCompile対象のShaderを制限する ● PreCompile対象のShaderを削減する
  131. 131. PreCompileのタイミングをズラす方法の問題点 タイミングをずらす・分散しただけなので、 ワーストケースでは数分レベルの待ち時間が発生 PreCompileするShader数が多いと パッケージサイズ、メモリ使用量にも悪影響が…
  132. 132. PSOキャッシュ機能を使う上で大事なこと (ほぼ)全てのShaderを PSOキャッシュの対象にしようとしない
  133. 133. (ほぼ)全てのShaderを対象としない理由 先述の問題 ● PreCompile処理時間、メモリ、パッケージサイズ PSOキャッシュの事前準備コスト ● ゲームを最初から最後まで 様々な行動をしながらプレイする必要がある ● しかも、2つのOSで苦労も2倍
  134. 134. どんなShaderを PSOキャッシュの対象にすればいいのか?
  135. 135. Shader Compileが必要なタイミング Shaderが初めて使われるとき オブジェクトを動的に生成したとき ヒッチが起きると遊びの邪魔になりストレスに レベルをロードしたとき 暗転・ローディング画面を表示中なことが多いため ヒッチが起きても影響が少ない PSOキャッシュで 優先的に対応すべきなのは こちら!
  136. 136. PSOキャッシュ対象のShaderを絞るためには… 対象のShaderを使用するオブジェクトのみを配置した PSOキャッシュ収集用レベルを構築・使用!
  137. 137. PSOキャッシュ収集用レベルの例 Qiita : UE4 Shader Pipeline Cache に 乗っていないShaderーを調査する (@Takezoh さん ) イカロスM ポストモーテム講演
  138. 138. EditorScripting で PSOキャッシュ収集用レベルを自動生成
  139. 139. PreCompile時間の問題への対策 ● PreCompileのタイミングをズラす ● PreCompile対象のShaderを制限する ● PreCompile対象のShaderを削減する
  140. 140. マテリアルの管理に注意しないと Shaderの数は簡単に膨れ上がります 数を抑えることで PreCompileの対象を減らせます
  141. 141. Shaderの組み合わせリスト
  142. 142. Shaderの組み合わせリスト Shaderの組み合わせを減らすと、Shaderの数は減る
  143. 143. Shaderの組み合わせリスト Shaderの組み合わせを減らすと、Shaderの数は減る (逆もまた然り)
  144. 144. この部分を減らすためには…
  145. 145. Shaderの数を減らす / 増やさないためには… その1 Material の Usage にて 不要な項目は必ず無効に ● Usage毎に別Shaderが生成されるため
  146. 146. この部分を減らすためには…
  147. 147. Shaderの数を減らす / 増やさないためには… その2 ( Mobile ) Shader Permutation Reduction を活用 ● プロジェクトで使用しない機能をOFFにすることで 不要なShaderの生成を防ぐ機能
  148. 148. 詳細はこちら https://www.slideshare.net/EpicGamesJapan/epic-games-japan-ue4dd
  149. 149. Shaderの数を減らす / 増やさないためには… その3 不要な設定・アセットが パッケージに含まれないようにする モバイル以外の プラットフォームも対応する際に重要
  150. 150. 詳細はこちら https://www.slideshare.net/EpicGamesJapan/ue4mobilestudy
  151. 151. PreCompile時間の問題への対策 ● PreCompileのタイミングをズラす ● 起動直後ではなく、ゲームフローに適したタイミングに ● PreCompile対象のShaderを制限する ● 動的に生成するものなど、ヒッチが目立つものを優先的に ● PreCompile対象のShaderを削減する ● 不要な設定を切ることで、Shaderの組み合わせを減らす
  152. 152. Shader Compile問題について ● なぜShader Compile問題が発生するのか? ● PSO キャッシュについて ● 概要・流れ ● 使うために必要な操作・設定 ● Tips ● PSOキャッシュによるPreCompile時間について ● ProgramBinaryCache ● ProgramLRUCache
  153. 153. ProgramBinaryCache ( Android OpenGL ES専用 )
  154. 154. OpenGL ES の PreCompileの問題点 OpenGL ES には Shader Compile結果を 次回起動以降に再利用する機能が標準では用意されていません 起動の度に、ソースコードからの Shader Compile という高負荷な処理が必要に
  155. 155. ProgramBinaryCacheとは? PSOキャッシュによるPreCompile結果を保存し 次回起動時に再利用することでPreCompileを短縮する機能 r.ProgramBinaryCache.Enable (デフォルト:有効)
  156. 156. PreCompile時間短縮効果 ProgramBinaryCache:無効 ● 1回目:4.41 s ● 2回目:2.03 s ProgramBinaryCache:有効 ● 1回目:4.36 s ● 2回目:0.54 s とあるプロジェクトにおける事例 2分 → 10秒 ActionRPG ( XperiaZ5 )で計測
  157. 157. ProgramBinaryCache 初回起動時 PreCompileの過程で生成された Program Binary (glProgramBinary) を ストレージに保存 ● /storage/emulated/0/Android/data/ <PACKAGE_NAME>/files/ProgramBinaryCache Shader ソースコード Shader Program Program Binary PreCompile 抽出
  158. 158. ProgramBinaryCache 2回目以降 PreCompile時に ストレージ内のProgram Binary から Shader Program を 生成 ● ソースコードからの変換に比べて格段に高速 ● FOpenGLProgramBinaryCache::ScanProgramCacheFile
  159. 159. PreCompile 開始 Program Binary は ある? ソースコード から Compile Shader Program 生成 Program Binary 保存 Program Binary から Shader Program を 生成 いいえ はい
  160. 160. 補足 ● 注意:PSOキャッシュ使用前提の機能です ● r.OpenGL.StoreCompressedProgramBinaries で更に圧縮可能 ただし解凍コストが発生 ● UE4.20以前は PSOキャッシュ関係なく バイナリを保存する機能でしたが、メモリ使用量などの問題で仕様変更 ( r.UseProgramBinaryCache )
  161. 161. ProgramBinaryCacheには PSOキャッシュによる初回PreCompile後に アプリを再起動する機能があります
  162. 162. 初回PreCompile後にアプリを再起動する機能 r.ProgramBinaryCache.RestartAndroidAfterPrecompile (デフォルト:有効) https://youtu.be/OAkKAqz709k
  163. 163. なんで再起動するん? ソースコードからのCompile過程で発生した 余分なメモリ消費をリセットするため PreCompile 開始 Program Binary は ある? ソースコード から Compile Shader Program 生成 Program Binary 保存 Program Binary から Shader Program を 生成 いいえ はい
  164. 164. 注意 デフォルトの場合、ユーザから見ると突然再起動が走ることに 再起動することを通知する画面があると安心 ● 再起動処理を行っている FOpenGLProgramBinaryCache:: OnShaderPipelineCachePrecompilationComplete()を拡張 プラットフォームによっては 再起動することにNG出る可能性も。事前に要確認 メモリに余裕のあるプロジェクトの場合は 無理に再起動しなくても問題なし
  165. 165. Shader Compile問題について ● なぜShader Compile問題が発生するのか? ● PSO キャッシュについて ● 概要・流れ ● 使うために必要な操作・設定 ● Tips ● PSOキャッシュによるPreCompile時間について ● ProgramBinaryCache ● ProgramLRUCache
  166. 166. ProgramLRUCache ( Android OpenGL ES専用 )
  167. 167. とあるプロジェクトで発生した問題 Adreno 端末: ● Program Binary 40MB から生成される Shader Program が 400MB以上 に Mali 端末: ● Shader Program の メモリ使用量が一定値を超えると描画が破綻 破綻のイメージ図
  168. 168. ProgramLRUCache メモリ使用量、又はShader Program数が一定値を超えた際に 使用頻度が低い Shader Program をメモリから破棄する機能 ● LRU = Least Recently Used r.OpenGL.EnableProgramLRUCache (デフォルト:無効) https://stackoverflow.com/questions/13337854/ understanding-lru-algorithm
  169. 169. 破棄を開始する基準について r.OpenGL.ProgramLRUBinarySize ● メモリ上に格納する Shader Program の 最大バイト数 ● デフォルト値:35*1024*1024 r.OpenGL.ProgramLRUCount ● メモリ上に格納する Shader Program の最大数 ● デフォルト値:700 デフォルト値は経験的に設定された値ですが 実際は端末によって最適値が異なります
  170. 170. メモリ
  171. 171. メモリ
  172. 172. Shader Compile ! メモリShader Program
  173. 173. Shader Compile ! Shader Program Shader Compile ! Shader Program Shader Program Shader Programによる メモリ使用量が増大
  174. 174. Shader Program Shader Program Shader Program Program Binary 使用頻度の低い Shader Program から 再生成用のProgram Binaryを作成
  175. 175. Shader Program Shader Program Program Binary 使用頻度の低い Shader Programを メモリから破棄 Shader Program
  176. 176. Shader Program Shader Program Program Binary Shader Programによる メモリ使用量が減少!
  177. 177. Shader Program Shader Program Program Binary 破棄したShader Programが 再度必要になると…
  178. 178. Shader Program Shader Program Shader Program Program Binary Program Binaryから再生成するので Shader Compileは走らない
  179. 179. Shader Program Shader Program Shader Program 再生成後、 Program Binaryをメモリから破棄 Program Binary
  180. 180. ProgramLRUCache のオプション r.OpenGL.ProgramLRUKeepBinaryResident ● 再生成用のProgram Binary を メモリ上に保持し続けるか否かの制御 ● デフォルト:無効
  181. 181. ProgramLRUKeepBinaryResident が 有効の場合
  182. 182. r.OpenGL.ProgramLRUKeepBinaryResident:有効の場合 使用頻度の低いShader Program を メモリから破棄するところまでは無効時と同じ Program Binary Shader Program Shader Program
  183. 183. r.OpenGL.ProgramLRUKeepBinaryResident:有効の場合 Shader Programを再生成した後も メモリ上に Program Binaryを保持し続けることが異なる点 Program Binary Shader Program Shader Program Shader Program
  184. 184. r.OpenGL.ProgramLRUKeepBinaryResident:有効の場合 Shader Programを再生成した後も メモリ上に Program Binaryを保持し続けることが異なる点 Program Binary Shader Program Shader Program Shader Program
  185. 185. パフォーマンス : 無効 < 有効 メモリ使用量 : 無効 > 有効
  186. 186. ここまでのまとめ ProgramBinaryCache ● Shader Compile結果をストレージに保存することで 2回目以降の起動時のPreCompile時間を短縮する機能 ProgramLRUCache ● Shader Compileによって生成された Shader Programのメモリ使用量を制限する機能 これらの機能を使っても問題が解決しない場合は 「PreCompile時間の問題への対策」を再度検討しましょう!
  187. 187. Shader Compile編のまとめ ● モバイルの場合、実機上でShader Compileが走るため 対策を入れていない場合は強烈なヒッチが発生 ● PSOキャッシュを使って PreCompile することで ユーザにストレスを与えるヒッチを回避可能 ● PreCompileのタイミング、Materialの管理、 メモリ使用量の調整など注意すべき点がいくつか存在 ゲームフローにも影響するため、 開発初期段階から検証・導入していきましょう!
  188. 188. おまけ rhi.Metal.CacheShaderPipelines ● Pipeline State Object(PSO)をメモリ上に保持し続けるか否か ● 有効(デフォルト):保持し続ける ● 無効: すべてのRHI参照が解放されると、PSOをメモリ上から削除 メモリ節約になるが、再利用時にPSOを再生成するコストが発生 https://docs.unrealengine.com/ja/Support/Builds/ReleaseNotes/4_22/index.html
  189. 189. Part 2へ

×