60fpsアクションを実現する秘訣を伝授 解析編【UNREAL FEST EAST 2019】

52.2K Views

October 08, 19

スライド概要

講演動画:https://youtu.be/YXGmiWzHxeo
基礎編:https://www.docswell.com/s/EpicGamesJapan/53M7JK-UE4_UFE19_Soleil_60fpsAction_Basic

2019年10月6日に行われた「UNREAL FEST EAST 2019」における「60fpsアクションを実現する秘訣を伝授」の登壇資料です。
●公式サイト
https://unrealengine.jp/unrealfest/
===
発売中のタイトル「NARUTO TO BORUTO シノビストライカー」に開発中のプロジェクトの事例も加えて、60fpsアクションゲームを実現するためのポイントや、パフォーマンス・チューニングについて解説します。おまけとして「NARUTO TO BORUTO シノビストライカー」のグラフィック面の技術を紹介。

profile-image

Unreal Engineを開発・提供しているエピック ゲームズ ジャパンによる公式アカウントです。 勉強会や配信などで行った講演資料を公開しています。 公式サイトはこちら https://www.unrealengine.com/ja/

シェア

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

60fpsゲームのために 解析編 Winter Crown WORKS 梶井 祐 協力: ソレイユ株式会社 尾田 委久 協力: Winter Crown WORKS 石濃 潤一郎 #ue4fest

2.

梶井 祐 • IndieGame Studio WinterCrownWORKSのプログラマー。 主に分野はグラフィックスプログラム。 仕事では各会社様からパフォーマンス関連のご相談を承って おります。 WinterCrownWORKSのアーティスト石濃、プログラマー梶 井で、アーティストとプログラマー両方の視点から改善案、 サンプル提供、エンジン改造などを行っております。 ご相談の際には contact@winter-crown-works.com までお気軽にご連絡ください。 #ue4fest

3.

はじめに • この解析編は基礎編でも触れた基本的な問題をクリアしてい る前提でのお話になります。 なので、「そんなところまで見るの?」と思う事もあるでし ょうが、より多くのものを画面に出しつつ、クオリティを出 そうと思うと必要になってきます。 • ここではより低レイヤーに近いところから解析、説明をして いきたいと思います。 #ue4fest

4.

目次 1.GraphicsをProfile 2. 軽量化、高速化に入る前に ...p7 ...p14 3.Maskedなマテリアル ...p17 4.BasePass 5.アセットについて 6.Translucency ...p69 ...p127 ...p179 7.PostProcessに関して ...p201 8.CPU軽量化、最適化 ...p214 9.オマケメモリに関して ...p267 10.総括 11.参考文献 ...p283 ...p289 #ue4fest

5.

テストに使ったPCの構成 • CPU i7-6700K 4GHz • グラフィックボード NVidia Geforce GTX 750 Ti • メモリ 64GB #ue4fest

6.

GraphicsをProfile #ue4fest

7.

ProfilingTool • コンソールは各コンソール専用のものがある。 • PC側も様々なものがあり、お手軽なものから低レイヤーの値 を見るものまで。 -PIX -RenderDoc -NSight -Radeon GPU Profiler …等々 #ue4fest

8.

Profilerで見ると何がいいの? • より詳細な情報が得られる(情報の精度、範囲はProfiler次第) - どんなデータがセットアップされたのか、シェーダース テージ間では何が受け渡されているのか? - 実際に描画されたポリゴン数は?ピクセル数は? - 計算が重いのか?テクスチャのアクセスか? #ue4fest

9.

この度使うProfilerはNSight 2019.5 • ダウンロードしてすぐ試せる。 • 低レイヤー部分の調査が出来る。(根拠のために必要) • NVIDIA様のドキュメントやBlogで多くの情報が得られる。 低レイヤーの情報も多く載っている。 • 【今人気のプラットフォーム】の解析に近 い感覚 #ue4fest

10.

NSight • NVIDIA 様のサイトより(翻訳): NVIDIA Nsight Graphicsは、グラフィックアプリケーション のデバッグとプロファイリングのためのスタンドアロンアプ リケーションです。 Nsightは、DirectCompute、Direct3D(11、12、DXR)、 OpenGL、Vulkan(1.1、NV Vulkan Raytracing Extension )、Oculus SDK、およびOpenVRで構築されたアプリケーシ ョンをサポートしています。 #ue4fest

11.

実行してキャプチャ → Profile結果 #ue4fest

12.

注意:管理者モードで実行にチェック • デフォルトの場合実行する際は常に管理者モードにしないと FrameCaptureが出来ない。 もしくは管理者以外にも カウンタを公開する。 #ue4fest

13.

軽量化、高速化に入る前に #ue4fest

14.

どんな問題がある? • • • • • Lightの置きすぎによるLighting負荷 広範囲に半透明を重ねすぎたOverDraw負荷 高解像度、テクスチャ枚数多すぎのマテリアル負荷 PostProcessによるフィルター負荷 草原、森の作り方によるMaskedMaterial負荷 等々・・・・。 #ue4fest

15.

ゲームエンジンを使用しても、なんでも お任せとはいかない・・・。 • 大前提として - デバイスの性能を上回る事はない - デバイスの影響は必ず受ける デバイスの性能を使い切るために Profileingを行い正確な情報を得る。 #ue4fest

16.

Maskedなマテリアル #ue4fest

17.

え?重いの? • 4.16で入ったMask Material only in Early Z-pass使ったら 軽くなるんじゃなかったっけ? 参考文献:Mask Material only in Early Z-passの効果と仕組 み • 抜きを使ったらポリゴン数少ないでしょ?軽いんじゃない の? #ue4fest

18.

整理しましょう。 • Mask Material only in Early Z-pass MaskedMaterialのBasePassの負荷は下がります。 が、 MaskedMaterialのすべてが解決する訳ではない。 • 板ポリの積極運用でポリゴンを減らす 抜きを使ってポリゴン数を減らして行っても、頂点数がボト ルネックのケースでない限りは効果は微妙 #ue4fest

19.

ポイント • Prepassの負荷 • ShadowDepthの負荷 • BasePassの負荷 Mask Material only in Early Z-pass で対処されるのはBasePassについて。 他の描画パスでは注意が必要。 #ue4fest

20.

Masked Material の実行 MaskMaterialOnly in Early Z pass未使用 • Prepass(Masked又は描画 しない) • BasePass(Masked) • ShadowDepth(Masked) MaskMaterialOnly in Early Z pass使用 • Prepass(Masked) • BasePass(Opaque) • ShadowDepth(Masked) #ue4fest

21.

BasePassはOpaqueだが他は・・・ • PrepassとShadowDepthにおいてはMaskedでレンダリング される。 つまりBasePass以外では依然としてMasked特有の制限を受 ける。 #ue4fest

22.

テストをしてみよう。 • 葉っぱ部分がMaskedMaterialで出来ています。 #ue4fest

23.

負荷の内訳 • Prepass 1.34ms • ShadowDepth 1.42ms • BasePass 2.31ms #ue4fest

24.

まずはPrepassを見てみる • 木の葉部分のみのDrawCallで 1.34msの内、1.06msも使わ れている。8割以上が葉っぱに使われている #ue4fest

25.

たかがこの程度の画面にしては重い • 60fpsは16.6ms その内1msがPrepassは妥当に見えますが、 画面の物量から見ると重すぎるように思える。 画面にもっとオブジェクトを載せたいのでもう ちょっと軽くしたいとか思いますよね? この際にやるべきことはポリゴンを削る事でしょうか? #ue4fest

26.

葉っぱ部分をProfile #ue4fest

27.

RangeInfo • DrawCall Count 1 Profileをかけた範囲で発生したDrawCallが1つ。 • API Primitive Total / Avg 投入されたポリゴン数の合計 / DrawCall辺りの平均 • Shaded Pixel Total / Avg ピクセルシェーダーの動作したフラグメント数 / DrawCall辺 りの平均 *PrepassでOpaqueマテリアルは 0 で計上される。(PDO を使ってない場合) #ue4fest

28.

PipeLineOverView • TOP SOL 各ワークロードの実行効率が最大理論値にどれだけ近いかの 割合 ここでは一番大きい値から5つ並べられます。 おおよその原因はこの辺りから順に割り出していきます。(各 ユニットは後述) #ue4fest

29.

GPU ユニット • • • • • • • • PD(Primitive Distribute) = インデックスバッファのロード VAF(頂点属性のフェッチ) = 頂点バッファの読み込み SM(ストリーミングマルチプロセッサ) = シェーダーの実行 FMA fp32(FADD,FMUL,FMAD) = 32bit浮動小数演算 ALU = 整数および論理演算 FP16 = 半精度の計算 SFU = 三角関数等(rsqrt,cos/sin ) TEX = SRV,UAVのフェッチ #ue4fest

30.

GPU ユニット • • • • • • VPC L2 CROP ZROP VRAM SOL = ViewPort変換、錐台カリング = L2キャッシュ = ColorRenderTargetへの書き込み、ブレンド = 深度ステンシルテストを行う = GPU Video Memory = Speed Of Light 理論値に対する達成率 #ue4fest

31.

SM Section • シェーダー実行に関する値になります。 この辺りは全部を解説しようとすると、複雑になり過ぎるた め、今回のボトルネックに関してだけ解説しようと思います。 SM Activeは100%に近い値が出ているため、ほぼ理論値が出 ている。 Stall部分が計上されているのが確認できる。 #ue4fest

32.

まず見るべき場所 • SOL TEX 100% , ZROP 42.9% , SM 21.9% , L2 20.8% TEXユニットへのアクセスが理論値最大で出ている。(テクス チャアクセスによって速度が制限されている可能性が高い) ZROPが高いのはPrepassは深度の構築なため深度に対する書 き込み、読み込みが多いため。 SMは若干低い気がする。 次にシェーダーの実行周りを見てみる #ue4fest

33.

SM Sectionを詳しく見てみる #ue4fest

34.

どう見る? • SM Active が100%に近いのにStall Long ScoreBoard が非 常に高い。 FS Invocations(ピクセルシェーダーの実行数)が非常に多 い。 #ue4fest

35.

MaskedMaterial おさらい • Prepass は Maskedのままでレンダリング - 抜きの計算のためにPixelShaderが走る 抜きのためのテクスチャアクセスも行われる。 - EarlyZが効かない 深度の裏に回ってもレンダリングされる。その上でピクセ ルシェーダーもテクスチャアクセスも行われるので尚負荷に #ue4fest

36.

α抜きの動作 • 流れ - 頂点シェーダー (画面に入っていた場合) Early Zを通り抜けピクセルシェーダーへ - ピクセルシェーダー OpacityMaskに繋がってるノードを計算。 αテストを通っていれば 深度テストへ(Late Z Test) - 深度テストを抜けた場合、DepthBufferへ出力 #ue4fest

37.

OpaqueMaterielの動作 • 流れ - 頂点シェーダー (画面に入っていた場合) 深度テスト(EarlyZ) - 深度テストを抜けた場合DepthBufferへ出力 ピクセルシェーダーは走らず、テクスチャアクセスも頂点で のフェッチまでしか発生しない。 #ue4fest

38.

EarlyZ(PreZ),LateZ(PostZ)に関して • ちょっとだけお話させて頂きます。 パイプライン上、深度テストのタイミングがより早い段階で 行われるものがEarlyZ。 深度テストがもっとも遅いタイミングで行われるものがLateZ になります。 尚、説明を簡略化するため、ReZの説明は省かせて頂きます。 #ue4fest

39.

描画パイプラインの深度テストの流れ 三角形 HiZ(階層Z/ステンシルテスト) EarlyZ(Z/ステンシルテスト) ピクセルシェーダー LateZ(Z/ステンシルテスト) カラーブレンド、出力 #ue4fest

40.

EarlyZ(PreZ) の深度テストの流れ • OpaqueMaterialがPrepass, Basepass,Shadowで行う 深度テストの流れです。 ピクセルシェーダー実行前に リジェクトできるので高速 三角形 HiZ(階層Z/ステンシルテスト) EarlyZ(Z/ステンシルテスト) ピクセルシェーダー カラーブレンド、出力 #ue4fest

41.

LateZ(PostZ) の深度テストの流れ • MaskedMaterialがPrepass時、 またはShadowDepth時に 行う深度テストの流れです。 ピクセルシェーダー実行後に リジェクトするので低速 三角形 HiZ(階層Z/ステンシルテスト) ピクセルシェーダー LateZ(Z/ステンシルテスト) カラーブレンド、出力 #ue4fest

42.

HiZって? • タイル単位に低精度で行う深度テスト 大雑把に大きい範囲で行うため、リジェクト自体は高速。 手前で大きい面積が深度でおおわれてるケースで効率的。 ハードウェアによってタイルのサイズは8x8,16x16等になる。 深度のビット幅も狭いので、本当に荒く深度テストを行う。 タイル分まるっと覆われてないといけない。 EarlyZ,LateZのどちらでも有効。 #ue4fest

43.

PrepassはMaskedの面積はそのまま負荷 に • 深度の裏に回った分もすべて負荷になる。 Maskedでレンダリングする際には、画面で見えてる以上に負 荷が高い という事に注意が必要。 今回の場合FS Invocationsが非常に多く、その上で TextureAccessも多い状態。 FS Invocationsはピクセルシェーダーが呼び出された数。 #ue4fest

44.

対処方法は? • 基本は面積を減らす事 裏に回っていてもピクセルシェーダーが走るため、重なる面 が多いほど負荷になる。 MaskedMaterialを減らす、頂点がボトルネックにならない程 度に抜きの形をとり重なる面積を減らす、面積を減らす為に LODを入れる、等が効果が出てくる。 *QuadOverDrawでは確認できないので注意 #ue4fest

45.

軽量化してみよう :少々変化球を用意し てみました。 • 実はLODモデルに仕込みがあり、Maskの領域が減っています。 #ue4fest

46.

モデルの構成: #ue4fest

47.

何をしたのか? LOD1からOpaqueのモデルが仕 込まれている 解説 • 中心に葉っぱの模様の球を Opaqueで入れる事で、葉っ ぱ部分を間引く。 こうする事でMaskの板の重 なりを大きく減らしつつ、 見た目のボリュームを維持。 #ue4fest

48.

計測してみる • Prepass が 1.34ms→0.83ms へ。 Mask部分に関して言えば0.55msと約半分に。 LODの分DrawCallは増えているものの軽量に。 #ue4fest

49.

MaskedMaterialそのものが軽くなった わけではないが・・・ • FS Invocationsが半分以下。 つまり単純に処理の総量が減っている。TEXが100%、Stall Long ScoreBardが高いのはMaskなので仕方ない。(Prepass全体では下がってる) #ue4fest

50.

Prepass まとめ • Mask Material only in early – Z-passを使っても注意が必要 • 重なる面積は最小に • 抜きの形状を綺麗にとるかどうかは配置数やシーン全体のポ リゴン数と相談 • 出来るだけ不必要なMaskを避ける 親マテリアルを意図せずMaskedMaterialで作っただけなんて いうケースも・・・。 #ue4fest

51.

実はShadowDepthも・・・ • ShadowDepthも同じようにMaskedMaterialの影響を強く受 けます。 基本的にはPrepassと同じような負荷の出方をします。 その上で、レンダリング先のバッファ解像度もカスケードの 影響が出てくるため注意が必要です。 Maskedとレンダリング解像度が原因のため細かい解説は飛ば しながら見て行きます。 #ue4fest

52.

LODなしのShadowDepth #ue4fest

53.

ShadowDepth 1.42ms 内訳 • 葉っぱ部分の合計が1ms #ue4fest

54.

ShadowDepth 1.42ms 内訳 • 床の部分もDynamicShadowを落としていた。 面積が広いため、合計が0.25msちょっとぐらい。 落としても見た目が変わらないなら積極的にオミット #ue4fest

55.

軽量化してみよう :Prepassの軽量化と 同じものです。 #ue4fest

56.

軽量版: 0.65ms • 何と半分以下!! #ue4fest

57.

葉っぱ部分の合計が0.45ms前後 • 葉っぱ部分だけを抽出しても半分になっている。(単純に書 き込む面積が減っただけですが) #ue4fest

58.

床はDynamicShadowを落とす先がない • 床部分はDynamicShadowを切りました。 影響する先がないため、切っても見た目が変わらないからで す。 その結果、各Cascadeからも床のDrawCallが消えました。 結果 0.25msの軽量化 #ue4fest

59.

解像度を2048→1024に落とす事でさら に半分の負荷に(見た目は変わる) • 0.30ms #ue4fest

60.

影の解像度は下げても良い? • Maskedの総面積がボトルネックになるという事は? 単純に影の解像度を下げても同じような効果を期待できそう です。 ただし解像度が下がった分、見た目を許容するのかは要確認 になります。 影がボケる、細かい影が消える等は向上する速度とのトレー ドオフ。 #ue4fest

61.

軽量化小ネタ:影モデルの利用 • 影モデル UE4のMeshComponentのRendering設定を調整する事で影 を落とすだけのComponentを配置することが出来ます。 #ue4fest

62.

影モデルを用意してどうするの? • 運用方法 - 影モデルとして配置するものはLODを1段下げる ポリゴン数を抑える効果、maskの場合は書き込みの総面積 の抑制効果による軽量化が出来ます。 - シルエットを合わせた別モデルを用意する。 こちらもMaskedの場合は総面積を減らせますし、シルエッ トを合わせる事でOpaqueMaterialで配置も出来るかも知れま せん。 #ue4fest

63.

ShadowDepthのまとめ • MaskedMaterialはDynamicShadowにも影響 重なる面積で負荷が非常にあがる • こちらもPrepass同様、無駄な書き込み面積を減らす事が重 要 • 解像度は要調整 BaseScalability.iniで各スケーラビリティごとに、 r.Shadow.MaxCSMResolution で解像度が設定されている。 タイトル側でiniファイルを作りスケーラビリティをタイトル の方針に合わせる。 #ue4fest

64.

MaskedMaterialのまとめ • Prepass と ShadowDepthで負荷に影響が出てくる。 重なる総面積に注意。 よく目にするBush(茂み)モデルはパッと見の見た目以上に重 なっているので、負荷が高い。 頂点をただ削られて総面積が変わらないデータを見る事があ りますが、広く重なる面積を減らす方が効果が高い事が多い。 FS Invocations 、Shaded Pixelの数が非常に大きい値になっ てないか確認を。 #ue4fest

65.

気づいたでしょうか? • 軽量化しようとするととっても手間がかかりますね? 軽量化、高速化には手間、コストがかかります。 「今時そこに手をかけるなんてナンセンス」なんて意見もあ る訳ですが、効果の高いやり方ほど手がかかります。 もちろん手間やコストをかけずに済ませられるならそれに越 した事はありません。 より良い知見があれば是非共有を‼ #ue4fest

66.

コストがかかるので • チームが何を求めているのかゴールをはっきりさせましょう。 手間のかかる事は後半には出来なくなります。 作業者も疲弊しているので、タスクを積んでも「無理」とおっしゃられ るか、雑な対応で戻ってくる事も往々にしてあります。 雑な仕事では効果は半減、クオリティにも影響します。 手間のかかる方法を実践する場合は、適応範囲を絞ったり、早々にスケ ジューリング、ワークフローを確立させる、作業者の確保等の戦略を立 てる必要があります。 *マネージメントの段階からの影響が大きい #ue4fest

67.

Maskedで気を付けるシチュエーション • 草原 • 森 • オブジェクトのカメラフェード これらのシチュエーションは負荷がかかる筆頭です。 もし大量に配置が必要な場合、なんらかの方法を確立したり コストをかけないとクオリティを下げる結果になりやすい。 *よく誤解がありますが、InstancingやFoliageを使っても ピクセルシェーダーの負荷は特別軽くなったりはしません。 #ue4fest

68.

Basepass #ue4fest

69.

ここからがNSIGHTの本領発揮です • ShadowDepthやPrepassは深度を書き込むだけの単純なパス なため、「NSightじゃなくてもいいじゃん」というものが多 かったです。 BasePassは非常に動作が複雑なため確認する価値が出てきま す。 時間やページの都合上かなり端折ってはいるのですが、出来 るだけ説明させて頂きます。 #ue4fest

70.

負荷のポイントが分かりづらい • BasePassはシェーダーの動作が複雑な動作をしやすい個所で す。 ノードの組み方自体複雑化するために、本当のボトルネック が隠れやすい。 あからさまなデータ以外はなかなか最適化が難しく、全体を 効率よくシェーダーが走るようにしないと、軽量化の差が出 てこないところも最適化が難しい部分になるかと思います。 #ue4fest

71.

負荷が重いケース 頂点シェーダー • 頂点シェーダーの負荷 - ポリゴン数の超過 - 頂点アトリビュートのデータサイズ 頂点座標やUV等のデータ。UE4だと主にUV部分や SkeletalMeshかStaticMeshかで可変する。 - シェーダーステージ間のデータサイズ カスタムUVで拡張、PixelShaderで使用される最大UVイン デックス(どういう事かは後述します) #ue4fest

72.

負荷が重いケース ピクセルシェーダー • ピクセルシェーダーの負荷 - 計算量が多い(ALU,FMA,FP16) - テクスチャアクセスが多い,大きいmipへのアクセス - 冗長なTexturFormatが使われている - RenderTargetのFormatが冗長 - PixelShaderの動く面積が広い - LateZの実行(PixelDepthOffset) - マイクロポリゴン、細長いポリゴンが多い #ue4fest

73.

サンプルシーン #ue4fest

74.

構成 • まず簡単なモデルデータのBasePassがどうNSightで解析で きるのか見てみます。 注目するデータ:消火栓モデル ポリゴン数 29,014 UVチャンネル 2 マテリアル:BC,Normal,MRの3枚 #ue4fest

75.

消火栓のマテリアル #ue4fest

76.

キャプチャしてみる。消火栓で0.179ms #ue4fest

77.

概要を見る #ue4fest

78.

TOP SOL • TEX が56.5%,SMも56.1% 上位のSOLが50%~60%、大変非効率に実行が行われている。 少なくともTextureアクセスによる制限は受けていそう。 CROPも40%と非効率な値になっているが、これは DeferredRenderingで出力先のGBUFFERが多いため仕方な いと思われる。 #ue4fest

79.

SM Sectionの詳細 #ue4fest

80.

値をそれぞれ検討してみる。 • SM Activeの割合が若干低い SM Occpancyも低く、シェーダーの実行効率が悪そう。 • Long ScoreBoardが高い L1の命令キュー待ちが多いほど高くなる。 (SM Occpancyが低くなってる原因ではないか?) • FS Invocationの値を見ると実行されているスレッド数が多い マイクロポリゴンが発生していないか? #ue4fest

81.

ちょっとユニットの補足 • L1 Cache Vertexのフェッチ、次のシェーダーステージへのアウトプッ ト、Textureのフェッチ時等でアクセスされる。 • L2 Cache L1でフェッチにミスするとアクセスが発生。 メモリアクセス時に頻繁にアクセスされる。 #ue4fest

82.

マイクロポリゴンについて • 表示面積が極小なポリゴン ROPユニットの都合上、1ピクセルのポリゴンや細長いポリゴ ンは効率が非常に悪い。 半ピクセルの面積もない場合 頂点をフェッチ→Viewport変換→カリング計算→ポリゴン化 できずにReject ただ無駄なだけの計算が発生する。 #ue4fest

83.

ポリゴンからピクセルが出力される例 • 一番左が3ピクセルが画面に出力、真ん中と右のケースはポリ ゴンが出来ない。 #ue4fest

84.

OverDrawも発生する。 • Opaqueにも関わらず3,4回もOverDrawされている個所があ る。 恐らく画面にOutPut出来ていないポリゴンもある。 #ue4fest

85.

PixelShaderの最小実行は2x2,8スレッド 分同時処理 • PixelShaderの最小実行単位は2x2のQuad単位になります。 32ピクセル分のスレッドをバッチ処理して出力する 。 つまりQuad以下であったり、細長いポリゴン、例えば【横に 11ピクセル分の直線に近いポリゴン】などは実行効率が悪い 状態です。 ポリゴン数が少ないものでもLODを作った方が良いのは、出 来る限りマイクロポリゴンを作らないようにするため。 #ue4fest

86.

とはいえコントロールは難しいですよね • 完全に最適にすることはできません。 配置場所、シチュエーションに応じて適切な作りにする、 LODを用意する、適切な場所で切り替える、ポリゴンの割方 を綺麗にする等を行う。 完全に遠景にしか置かないと分かっているものは遠景用のも のを作るべきかどうかも検討材料です。 #ue4fest

87.

まとめると • テクスチャアクセス より小さいmipアクセスにする。 1回のサンプリングで出来るだけ情報を拾えるように各チャン ネルにマージする。 *アトラス化の事では無い事に注意‼よく勘違いされる事が あります • マイクロポリゴンを削る 見た目が変わらない程度であっても、ピクセルシェーダーの 実行数が減るため、頂点負荷以外も軽くなります。 結果的に同じ面積でメモリアクセスも減る。 #ue4fest

88.

で、軽量化をしてみた #ue4fest

89.

マテリアルの軽量化 • RG:NormalMap+B:Metallic+A:Roughnessでテクスチャを パックすることでサンプリングを一回減らしました。 TextureはLinerTexture #ue4fest

90.

オマケ:UnPackNormalのコード CustomShaderノードの中身です。これ自体はunreal内で宣言されているコードとほぼ同一のもの になります。 MaterialFloat2 NormalXY = vRG.rg; NormalXY = NormalXY * MaterialFloat2(2.0f,2.0f) - MaterialFloat2(1.0f,1.0f); MaterialFloat NormalZ = sqrt( saturate( 1.0f - dot( NormalXY, NormalXY ) ) ); return MaterialFloat4( NormalXY.xy, NormalZ, 1.0f ); #ue4fest

91.

LODで細かいポリゴンを削る。 LOD 0 LOD 1 #ue4fest

92.

OverDrawの比較 LOD0 LOD1 #ue4fest

93.

解析してみる。 • 0.03ms~0.04msの速度向上が見られる。 単なるノイズかも知れないので、さらにProfileをかけてみる 事に。 #ue4fest

94.

TOP SOLの順位が変わっている • 以前のTOP SOL は TEX が56.5%,SMが56.1% #ue4fest

95.

さらに詳しく #ue4fest

96.

考察 • Long Scoreboard 、Tex Throttle 共に下がっている。 テクスチャアクセスを減らしたことでL1の待機が減ったと思 われる。(TEXのSOLも下がっている事が確認できた) • FS Invocationが下がっている。 見た目の面積は一緒だが、マイクロポリゴンやOverDrawが 減った事により、ピクセルシェーダーの実行が減っている。 • SM Active Min/Maxも少し上がっている 多少シェーダーユニットの並列性が上がったものと思われる。 #ue4fest

97.

まだ効率は悪いが・・・ • TEX,CROPが中途半端で気になる割合。 Textureのアクセス枚数は減らしたものの効率が悪い。 2048x2048のテクスチャで、カメラ近くで映っているので 大きいmipアクセスが発生しているように思われる。 CROPはレンダーターゲットへの出力。 DeferredだとGBUFFERが多くどうしてもネックになる。 #ue4fest

98.

CROPの軽量化 • CROPが気になる割合。 SceneRenderTargetのフォーマットを下げる、Sceneの解像 度を下げる、出力バッファ枚数を減らす。 今回のシーンのフォーマットは既にR11G11B10Float。 GBUFFERの枚数を減らす事に関しては、Forwardにする以外 のやり方だとエンジンを改造しないといけない。 Forwardにしたとして、テクスチャアクセスとLightingの分 の計算がBasePass内で増える。効率の意味では効果はいまい ち #ue4fest

99.

TEXの軽量化 • できるだけ低いmipへのアクセス 必要がなければTextureの解像度を下げる • 単色やグラデーションだけのテクスチャはパラメーターに置 き換える • TextureFilterを必要最小限に Anisotropyを低いレベルに指定する等でもう少し改善は出来 ると思われます。 #ue4fest

100.

負荷のかかりやすい場所 • 実際のデータで想定すると もっと複雑にブレンドしたりアクセスするテクスチャ枚数が 多かったり、不必要に大きい解像度のテクスチャ という事 が多いと思います。 細かい計算よりはメモリアクセスの方がボトルネックのケー スは多く、メモリアクセスの遅延により計算、instructionを 隠蔽できるケースが多い。 計算が負荷として問題になるのはVoronoiNoiseのような極端 なinstruction数が増えるケース。 #ue4fest

101.

オマケ:Imposter Baker • 最近、結構誤解がある と感じたので軽くImposter Bakerに 触れておきます。 こちらはモデルを多方面からキャプチャした画像を使い、視 点方向に合わせたテクスチャを選択し、補間を行い、板ポリ でモデルを表現するような手法になります。 #ue4fest

102.

板ポリなら当然軽いでしょ #ue4fest

103.

・・・本当にそうですか? #ue4fest

104.

軽いかどうかはケース・バイ・ケース • こんなシーンを作ってみました。 左がモデル、右がimposter Bakerで作成した板ポリです。 #ue4fest

105.

まずはRendering時間の比較 Imposter Prepass+BasePass=0.047ms Model Prepass+BasePass=0.022ms #ue4fest

106.

画像が見づらかったのでもう一度 • #ue4fest

107.

意外でしたでしょうか? #ue4fest

108.

Imposter : 概要 #ue4fest

109.

Imposter : 詳細 #ue4fest

110.

Model : 概要 #ue4fest

111.

Model:詳細 #ue4fest

112.

一見するとImposterの方が効率良さそう に見えるが・・・ • TOP SOLのTEXの割合はImposterの方が高い そしてL2のHitRate 、SOLがImposterの方が低い。 角度補間のために同じテクスチャへのサンプリングが多く、 キャッシュミスが多いためと思われる。 • ShortScoreBoardがImposterの方がかなり高い。 恐らくUVを求めるための計算が非常に長い。 • FS InvocationsもImposterの方が高い。 つまり上記二点のボトルネックがあるにも関わらずピクセル シェーダーの実行数も多い #ue4fest

113.

今回使ったImposterはSamplers5,TextureLookUpsが 24 とかなり多い。 #ue4fest

114.

Model側:Samplerは5,Texture Lookups は2、Instructionsも少ない。 #ue4fest

115.

表示面積の違い #ue4fest

116.

Imposterを使う事が有効なケース • 頂点がシーンのボトルネックのケース • 表示領域が十分に小さい事,見る方向を変化させてもできるだ け一定の大きさである事。 • 用途に合わせてマテリアルも最適化した方が良い。 PixelDepthOffsetの使用を最低限にしたり、ライティングの 有無。 #ue4fest

117.

まだちょっとネタがあります #ue4fest

118.

頂点Attribute • ポリゴン数が多い場合に、よりネックになってくる部分です。 頂点アトリビュートは頂点の入力属性。 UE4のStaticMeshにおいてはInstancingとUVに気を付ける事 になります。 SkeletalMeshはそもそもアトリビュートが多いため、ポリゴ ン数の負荷がロースペック環境だと、比較的高くなりやすい です。 *対応方法はUVチャンネル数を抑えるぐらいしか出来ないた め割愛します。 #ue4fest

119.

シェーダーステージ間のデータ • 主に VertexShader → PixelShader で受け渡されるデータ このサイズが大きいとシェーダーの実行効率が落ちます。 PSが起動する際、このデータを読み取り終える必要があるた めです。 こちらは、PS内で使うUVが多い場合(CustomUVでの拡張も 含む)、Vertex InterpolaterノードでPixelShaderへデータを 受け渡した場合にサイズが増えます。 #ue4fest

120.

拡張前のマテリアル:VSの出力 #ue4fest

121.

CustomUVでUVを拡張する • UV7にUV0を出力して、PSでUV7でテクスチャサンプリング を行います。 #ue4fest

122.

使用するレジスタ数が増えました。 • 尚、CustomUVを使わなくてもTextureCood に入れた最大 の大きさのindexでoutputは拡張される #ue4fest

123.

で、BasePassが重い原因って? TextureAccess マイクロポリゴン RenderTargetのフォーマット ポリゴン数が多いケースで、VS to PSのoutputParamaterの サイズ。 • 極端に多いポリゴン数 • PixelDepthOffset (UE4においてはBasePassでもHizが効く LateZの実行という感じ) 等々・・・・。 • • • • #ue4fest

124.

原因が多すぎない? • 組み合わせもありますし、非常に多いです。 そして、基本的なものが守られた上での状態であれば、対処 をしても一個一個に対する効果は薄く、塵を積もらせていく ことになりやすいです。 ゲームによっては多少の負荷は目をつぶっても良いと思いま す。 しかし60fpsのゲームにおいては0.5ms捻りだすだけで軽めの PostProcess1個分捻出できたりするので、必要があるケース というのはあります・・・・。 #ue4fest

125.

シーンのポリゴン数を気にする • シーン内のインスタンスが多いオブジェクト その上でOcclusionに引っかかりづらい位置のもの • Instancing系の機能 • 大きいサイズのモデル(BoundingBoxの大きいもの) • 極端にポリゴン数が多いモデル。(数十万など) これらには十分注意が必要です。 カリング効率が悪いオブジェクト達が増えるとポリゴン数がボ トルネックになる事はおおいにあり得ます。 #ue4fest

126.

アセットについて #ue4fest

127.

概要 • ここまでで通常使われるようなモデルが関係するPrePass、 Shadow Depth,BasePassを扱ってきました。 ここからアセットに注目した話をしていきたいと思います。 #ue4fest

128.

負荷の原因はアセットにあり? • アセットはそこにあるだけで負荷になります。 一つ一つは大した負荷ではなくてもチリツモで取返しのつか ない事態に 開発終盤で追加したい項目があっても負荷が高ければ諦める 事にも →ゲーム要件の減少 #ue4fest

129.

アセットを調べよう • 専門のスタッフ(グラフィックスプログラマー)がいるなら 協力を仰ぎましょう。 よほど専門的な知識が無ければゲームデザイナー、アーティ ストだけでは調査しきれません。 ユースケースだけに頼らないように、調査し根拠を詰めます。 #ue4fest

130.

LODを設定しましょう • 近景に物が置かれた状況でLODが必要ないケースは稀ですの で、必ず導入を検討しましょう。 基本的なことですが、アセットの数が何百何千個とふえてく ると確認がおろそかになります。 ステージに配置した数万個のアクターがLODモデルに切り替 わらないというケースを見かけた事もあります。 意図した動作をしているか確認を‼ #ue4fest

131.

LODの状況を確認しましょう • 実際の画面で適切 に切り替わってる か確認しましょう。 #ue4fest

132.

崩れにくい形状 #ue4fest

133.

崩れやすい形状 #ue4fest

134.

ジャンルの影響を受ける • SFや現代劇は角ばった構造物が多く軽量化しにくい。 ファンタジーや自然を取り扱ったものは流線型が多く軽量化 しやすい。 扱うジャンルによってリダクションの難易度に差がでてきま す。 *角ばったものはシェーディンググループが切れやすく、見 た目より頂点が多かったり、Primitiveが非効率になりやすい。 #ue4fest

135.

マテリアル • メタリック、ラフネスは省略しやすい(パラメーターで済む ケースが多い) #ue4fest

136.

テクスチャストリーミング • 3Dゲームの場合カメラが不用意に近づくことがあります。 その際、巨大なテクスチャにアクセスされ負荷になっても困 るので最大サイズは必要最小限にしておきましょう。 #ue4fest

137.

テクスチャサイズ • UE4上でデータごとに設定していると管理が煩雑になるので テクスチャの割り当てサイズはアセットの形状、サイズから 適切にルール化しましょう。 2K,4Kのテクスチャは(PSDも含むと)サーバー容量を圧迫し、 作業コストを増大させます。 開発終盤でサーバー容量が不足する経験をしている人はそこ そこいるのではないでしょうか? #ue4fest

138.

テクスチャ 最大サイズはどうする? 1Mのボックスに岩のマテリアルを適用 当たり前ですが左の方がディティールが出ていて綺麗 サイズ2048 サイズ512 #ue4fest

139.

テクスチャ 最大サイズはどうする? サイズ2048 サイズ512 #ue4fest

140.

テクスチャ 最大サイズはどうする? 前画像をアップ ミップマップがかかりほぼ同じ見た目に サイズ2048 サイズ512 #ue4fest

141.

テクスチャ 最大サイズはどうする? サイズ2048 サイズ512 #ue4fest

142.

テクスチャ 最大サイズはどうする? 前画像をアップ 右がややシャープに? サイズ2048 サイズ512 #ue4fest

143.

テクスチャ 最大サイズはどうする? • 登録されたテクスチャサイズが大きいとユーザーの操作によ りイレギュラーでカメラの目の前に写ってしまい大きなサイ ズで読み込まれて想定外の負荷に。 客観視点のゲームではカメラがキャラクターの背後にありま す。 通常のゲームプレイに則った距離感を想定しておくとテクス チャの適切なサイズが割り出しやすくなります。 #ue4fest

144.

ヒートマップに沿ったリソースの割り振 り #ue4fest

145.

アセットのサイズや分割、まとめ • アセットは大きすぎても、細かすぎてもいけないものになり ます。 ここからはまとめ方に注力してお話させて頂きます。 もちろんこちらも、前ページのヒートマップに沿ったリソー スの割り振りが重要になります。 #ue4fest

146.

広さ 狭い方がコントロールしやすいが・・・。 #ue4fest

147.

視点 トップビュー 画面に収まる情報量(リソース)をコント ロールしやすい #ue4fest

148.

視点 プラットフォーマー いわゆる横スクロール こちらもリソースコントロールはしやすい #ue4fest

149.

視点 3D 3D視点は遠くまで見渡せる ユーザーの視点を制御しにくく、他視点よ りもリソース管理が難しい #ue4fest

150.

オブジェクトの属性 静的か? →まとめやすい 破壊オブジェクト(動的か?) →まとめにくい まとめるか否か #ue4fest

151.

まとめたいケース • DrawCallが多すぎる、OcclusionCullingやトラバースが負 荷になってしまう。 まとめる事でテクスチャアクセスが増えたり、1モデルの Primitive数が増えたり、マテリアルが冗長なものになってし まう事には注意が必要です。 配置が細かすぎる時にはOcclusionCullingがCPU側のボトル ネックになる事もあるので、まとめる事も、細かくすること も程々に。 #ue4fest

152.

カリングとアセットサイズとアクター数 • カリングを考慮してアセットのサイズを決める時何を考える でしょうか? アセットが大きい→カリング効率は下がるがアクター数は減 少 →GPUを圧迫しやすい アセットが小さい→カリング効率は上がるがアクター数や DrawCallは増加。 →CPUとメモリにしわ寄せが。 #ue4fest

153.

GPU,CPU,メモリ • どれか一つ破綻してもゲーム開発は苦しくなります。 負荷ができるだけ偏らないように分散を。 #ue4fest

154.

簡単なカリング例! 背景アセット 背景アセット 椅子は一つ一つ分けておけば、カ リング処理で片方は弾く事ができ そうです。 カメラ キャラクター ゲーム画面 この椅子は描画せずに済む #ue4fest

155.

簡単なカリング例? 全体を俯瞰 ではこう配置されたら? ある程度はまとめていいのかも #ue4fest

156.

適切なアセットサイズ まとめと分割 • どう分けるか、どうまとめれば効率的なのか? 販売ターゲットによってはある程度の負荷は許容できるかも 知れません。 時間が取れずに作業効率を優先するかも知れません。 どうしても大事な場面のため時間をかけて最適化する必要が あったり。 条件が多すぎるためケースバイケースになります。 #ue4fest

157.

適切なアセットサイズ まとめと分割 別な例で考えましょう この場合はどう分けた方がよいでしょうか? #ue4fest

158.

適切なアセットサイズ まとめと分割 天井は視界に入りにくいので別アセットに分けるとカリング効果が高い 横から #ue4fest

159.

適切なアセットサイズ まとめと分割 俯瞰 床はどこを向いても視界に入ってくるので切りに くい 左右の壁は視界によってはカリングできるので切 りやすいです。 カメラの視界を大雑把に考慮すると・・・ カメラ #ue4fest

160.

適切なアセットサイズ まとめと分割 俯瞰 岩壁はこれぐらいには分割したい #ue4fest

161.

適切なアセットサイズ まとめと分割 #ue4fest

162.

分割はすでにしてあるが・・・ • これだけ分割してあればカリング効率は最高です。 では細かくしておけば問題ないのでしょうか? この部屋だけでゲームが完結するなら問題ないかも知れませ ん。 ではもっとたくさんの部屋で1ステージが構成されていた場合 は? #ue4fest

163.

1ステージの構成 通常のレベルデザインでは複数の空間からステージを構成 することになるでしょう。 アセットの数も要素とともに増えていきます。 アクター数と描画負荷、メモリ 上記要件の決定にはゲーム要件に照らし合わせながらバラ ンスを取る事が求められます。 #ue4fest

164.

最適化の影響と効果 • ゲーム企画→最適なデータ構成を決定していく過程で データの構成をめぐってグラフィック担当に影響します。 設計に跳ね返るとプランナーにまで影響が及びます。 最適化を最後にエンジニアに任せればいいと考えていると余 計なコストを支払うことになります。 →処理落ちの原因の多くは設計→アセットにあるため #ue4fest

165.

最適化の影響と効果 • つまり、最適化の効果は・・・・ エンジニアだけが対応 → 効果小 グラフィッカーも協力 → 設計段階から考慮 効果中 → 効果大 #ue4fest

166.

ゲーム設計は出来るだけ早めに • プランナーやゲームデザイナーは最適化まで考慮する必要は ありませんが設計は早めに固めましょう。 設計が早く固まればアーティスト、プログラマーがゲーム内 容を損ねないような最適化の着手を早いタイミングで行えま す。 設計待ちの状態が続くと作業者は作業効率を優先してアセッ トを整理しません。できません。 結果、アセットが重い状態で放置され続けます。 #ue4fest

167.

選択肢を絞るために • 植物や動物は生きるのに適正な環境下にいます。 家など建築物は手に入る資材で作られます。(もしかしたら 他国からの輸入などかも知