UnrealEngine レンダリングシステムとその拡張

78.8K Views

November 19, 23

スライド概要

profile-image

いろいろやってます。

シェア

またはPlayer版

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

関連スライド

各ページのテキスト
1.

Unreal Engine レンダリングとその拡張 RHI? RDG?

2.

自己紹介 すとんりばー ● ● ● ● ● Unreal Engine / C++ / Rust / Linux などが好き。 趣味は読書と創作。 2000年生まれ。高専中退中卒エンジニア。 現在(2023年11月)はAlche株式会社所属。 前回はマルチプレイの話をした。 技術ブログ: strv.dev GitHub: strvert Twitter : @strvert STONRIVER ( Riku Ishikawa )

3.

この資料の目的 本資料は、Unreal Engine のレンダリングシステムを走 り抜けることを目指している。 描画処理 (PBRとかDeferred Renderingとか)の内側には 触れない。 厳密な表現よりも直感性を優先している箇所があることに注 意。

4.

この資料でわかること この資料は、以下のようなことを扱う。 - Unreal Engine はどうやって様々なプラットフォームにグラ フィックス機能を対応させているのか? - レンダラがどのように呼び出されるのか? - コンテンツの情報がどのようにレンダラで扱われるのか? - UE のレンダリング処理を拡張するにはどんな方法がある か?

5.

前提:グラフィックスAPI

6.

前提:グラフィックスAPI 画面に画を描画するためには、GPU やそれに相当するハード ウェアに絵を作ったり、ディスプレイに出力してもらったりし なくてはならない。 しかし、ハードウェアを直接操作する実装を各コンテンツが独 自実装するのは現実的でも適切でもない。 そこで、GPU などのハードウェアの機能をうまく扱うための 仕組みと方法をまとめた API の仕様を、様々な組織が作成し て公開している。それがグラフィックスAPI。

7.

前提:グラフィックスAPI 代表例は DirectX (Microsoft), Vulkan (Khronos), Metal (Apple) など。 こうした API を通してグラフィックス機能を利用して実装す ることで、ハードウェアの詳細に依存しないアプリケーション が実装できる。

8.

前提:グラフィックスAPI しかし厄介なことに、すべてのグラフィックスAPIがすべてのハー ドウェアやプラットフォームで利用できるわけではない。 利用できても、最も適切な API は違うこともある。 各 API の仕様は違うので、同じコードを流用できない。

9.

前提:グラフィックスAPI ここで、UE で標準的に利用されるグラフィックスAPIとプラット フォームの対応を見ると、次のとおり。 プラットフォーム 推奨 利用可能 Windows DirectX12 DirectX12, DirextX11, Vulkan, OpenGL iOS / macOS Metal Android Vulkan, OpenGL ES Vulkan, OpenGL ES 大変そうなことがわかる。では UE はグラフィックス系の機能をい ちいち全プラットフォームの全APIに向けて再実装しているのか? もちろん、そんなことはない。

10.

Rendering Hardware Interface (RHI)

11.

RHI (Rendering Hardware Interface) RHI は、各種グラフィックスAPIを抽象化しているUE内部のレイヤ。 UE がグラフィックス機能を実装するときには、プラットフォームの APIを直接叩くのではなく、RHI を使って実装するようになっている。 UE 独自の内部グラフィックスAPI のようなものとも言える。

12.

RHI (Rendering Hardware Interface) おかげで、個別APIへの対応は RHI の裏側に隠され、Engine の膨大な 機能をAPIごとに個別実装しなくて済む。 言い換えれば、UEを利用する開発者も RHI を使ってグラフィックス機 能を実装することが可能で、その機能はAPI非依存にできる。

13.

RHICommand RHI を通して命令を出すときには、RHICommand を発行する。 RHICommand は RHI が提供する プラットフォーム非依存API の機能 単位。各 RHI コマンドは、何らかのプラットフォームAPI呼び出しに 対応している。 エンジン本体で100種類くらい、ビルトインプラグインにも10種 類くらい含まれている。 RHI のどんな操作も、最終的には 「RHICommand の実行」として実 現される。

14.

RHICommand のキューイングとフラッシュ RHICommand は、一つずつ実行され るわけではなく、キューにためて、適 切なタイミングでまとめて実行する。 ここで、RHICommandListが登場す る。RHICommand を入れておくコマ ンドキューで、複数コマンドを組み合 わせたハイレベルなAPIを提供する ラッパーでもある。 ……なぜこんなキューを使うのか?

15.

Parallel Rendering (並列レンダリング)

16.

グラフィックス API 昔話 古典的なグラフィックス API を使ったレンダリングシステムの 1フレームを簡易的に示してみる。 ※ 昔話ではないケースも多々ある

17.

グラフィックス API 昔話 ● 指示役(CPU)がワンマンすぎる ● CPU と GPU が並列で動けない ● このチーム構成ではどうしようもない ※ 昔話ではないケースも多々ある

18.

マルチコアと非同期グラフィックスAPIの時代 現代では、CPU が複数のコアを持つことが普通になった。 また、グラフィックスAPI は非同期APIを持ち、CPUをブロックし なくなった。 ※ これは簡易図で、UE のレンダリングシステムを示すものではない

19.

マルチコアと非同期グラフィックスAPIの時代 現代では、CPU が複数のコアを持つことが普通になった。 また、グラフィックスAPI は非同期APIを持ち、CPUをブロックし なくなった。 ゲーム処理担当 レンダリング処理担当 分担してフレームを更新 GPUにはコマンドを送る コマンドの結果の終了は待たない ※ これは簡易図で、UE のレンダリングシステムを示すものではない

20.

コマンドキュー ≒ GPUのタスクボード つまり、非同期 API をサポートしたグラフィックスAPIでは、GPU の処理を呼び出して結果を待つではなく、GPUにコマンドで処理 を依頼しておいて、自分は別のことをするような仕組みに変化して いった。 すると、GPU が未完了タスクを順に確認できるタスクボードがほ しくなる。ここで登場するのがコマンドキュー。 CPU はタスクボードにコマンドを詰めて行けば良いし、GPU は適 切なタイミングでコマンドを取り出して作業をすれば良い。 非同期処理での通信用データ構造として、用意されている。

21.

UE スレッドモデル

22.

スレッドってなんぞ スレッドは、OS のプロセス上で動作する一連の処理の単位。 一つのスレッドでは一つの命令列しか同時に実行されない。 複数のスレッド(マルチスレッド)を活用すると、同時に複数の命 令列を実行できる。マルチコア 環境では、プログラムの処理を多 数のコアに分散することで効率化が図れる。 自然にはそうならないので、マルチスレッドのためのプログラミ ングをする必要がある。 ※ 語弊を含む。Concurrent / Parallel で検索

23.

UE の名前付きスレッド - NamedThread UE には、いくつかの主要なスレッドが存在する。 特にレンダリング関係に絞って並べる。 ● Game Thread ○ UE のメインスレッド。普段書く処理(BPとかも)ここで走る。 ● Render Thread ○ Game Thread の更新や命令を受けて、描画系の処理や命令の構築を行う。 ● RHI Thread ○ Render Thread 等で構築された RHI Command 受け取り、プラットフォー ムAPIを通して GPU を動かす。 ※ 環境や設定によっては全部GameThreadになったりもするぞ

24.

その他のスレッド - Workers UE に存在するのは Named Thread だけではない。環境のCPUコ ア数などに応じて個数がスケールするスレッドもある。 Worker(複数種ある) と言われるスレッドは、専門の役割は持たな いが、Named なスレッドから必要に応じてタスクを依頼され、 処理を実行する。 なお、Named 含むこうした UE のスレッドは、TaskGraph とい うシステムによって制御されている。

25.

Unreal Insights で見てみる Game Thread Render Thread RHI Thread Render Thread Workers #19 #20 #0 #1 #2 #3 #4 #5 #6 #7 #8 #9 #10 #11 #12 #13 Worker の数は環境依存 この図は見切れてる

26.

RenderThread への依頼 異なるスレッドと連携して仕事をするには、何らかの方法で通信 を行う必要がある。 特に、UE でグラフィックス機能を扱うコードを書くときには、 必ず RenderThread で実行しなければならない。 GameThread から RenderThread に処理を実行させることがよく あり、頻出ゆえに専用の方法が用意されている。

27.

ENQUEUE_RENDER_COMMAND void HogeFunction() { // ここは関数を呼び出したスレッドで実行される const FColor Color = FColor::Red; ENQUEUE_RENDER_COMMAND(HogeRenderTask)( [Color](FRHICommandListImmediate& RHICmdList) { // ここは RenderThread で実行される。 // ラムダ式のキャプチャーによって データを RenderThread に渡せる。 const FColor RenderThreadColor = Color; // RenderThread で実行されるコードを記述する。 // RHICmdList に描画コマンドを追加していくことで、グラフィックス命令を発行できる。 } ); }

28.

ENQUEUE_RENDER_COMMAND このマクロは、RenderThread で実行すべき処理のキューにラム ダ式を Enqueue するユーティリティ。簡単に RenderThraed に 処理を投げることが可能で、エンジンでも頻用されている。 渡すデータの扱いには注意が必要。 オブジェクトおよび処理のライフサイクルやアトミック性を意識 しないとクラッシュを招く。

29.

GameThread / RenderThread シーン表現

30.

シーン表現? ここでのシーン表現とは、オブジェクトの配置情報やモデルの種 類、マテリアルなどからなる、一つの画面空間を再現可能な情報 のセットと方法のこと。

31.

GameThread でのシーン表現 GameThread 、すなわち普段BPなどで操作しているスレッドにあ る空間は、おおむね次のような構造で表現されている。

32.

GameThread でのシーン表現 ● UWorld ○ 実行中の空間コンテナ。見た目だけでなく GameInstance とかプレイヤー情報と か、ゲームにおけるあらゆる空間情報の入れもの ● ULevel ○ 配置情報とか実行中に行う処理とかの情報を持ったコンテナアセット。 ● AActor ○ 空間に配置できるオブジェクト。処理とコンポーネントのコンテナ。 ● UPrimitiveComponent ○ AActorにアタッチできる。「見える」ものすべての親。 ● ULightComponent ○ AActorにアタッチできる。「光源」すべての親。

33.

RenderThread でのシーン表現 RenderThread でも GameThread のオブジェクトが活躍するかと 思いきや、そんなことはない。 おそらくマルチスレッドプログラミングにおける複雑性を回避す るために、RenderThread には GameThread の世界からレンダリ ングに必要な情報だけを抜き出したミラー世界が構築される。

34.

RenderThread でのシーン表現 型 説明 FScene UWorld に相当。Light や Primitive をはじめとして、シーンの見た目に関する全情報 をRender Thread で持つための構造。BP やゲームロジックなどは一切持たない。 GameThread からフレーム更新時に状態の更新を受けることで、同一性を維持する。 FPrimitiveSceneProxy UPrimitiveComponent に相当。任意のメッシュを表現し、メッシュタイプ、描画のた めに必要なシェーダー、パラメータ等を保持する。 FPrimitiveSceneInfo FPrimitiveSceneProxy に情報を足したもので、「FScene 上の FPrimitiveSceneProxy」としてレンダラで扱うための情報やインターフェースを持 つ。 FSceneView / FViewInfo FScene内の投影情報を表す。どこから見るか、どのような変換で画面にシーンを投影 するかなどのパラメータと計算ロジックを持つ。 FSceneViewState ULocalPlayer の View と対応し、フレームをまたいで特定のViewの状態を扱う。 FSceneRenderer 上記すべての情報を使って、レンダリングを実行、画面を作り出す。 派生クラスに FDeferredShadingSceneRenderer / FMobileSceneRenderer など。 たくさん書いてますが、伝えたいことは RenderThread には描画専用の世界がミラーされているということです。

35.

RenderThread へのシーン情報の同期メカニズム (時間の都合上割愛してしまうが、大変重要) 毎フレームすべてのシーン情報を複製するのは無駄なので、可 動性などをもとに更新分の同期を最適化しています。

36.

RDG (Rendering Dependency Graph)

37.

RDG (Rendering Dependency Graph)?? RDG は、 RHI の上に構築された、レンダリング命令およびリ ソースに対するスケジューリングシステム。 比較的新しいシステムで、UE4.22 の頃の登場したらしい。 UE4.26 からはシーンのレンダリング(BasePassなど)もまるごと RDG による記述に置き換えられた。 ※ おかげで以前のレンダリング機構解説の具体部分が参考にならなくなった

38.

RHI + RDG = うれしい 置き換えられたと言っても、記述の意味が変わったわけではな い。RDG が提供する以下のような特性により、開発と実行が効率 化された。 ● ● ● ● ● ● レンダリングリソースの管理。スコープベースの遅延確保と自動開放 レンダリングコマンド発行をワーカースレッドへ自動分散 コマンドを実行前に「コンパイル」してパスを最適化 直感的な記述性 RDG 向けに用意された多数のユーティリティ関数 デバッグ容易性の向上

39.
[beta]
具体例を見てみよう
与えられた RenderTarget2D を単色で塗りつぶすサンプル
void URenderingPracticeLibrary::ClearTexture2D(UTextureRenderTarget2D* Texture2D, const FColor& Color)
{
ENQUEUE_RENDER_COMMAND(ClearTexture2D)(
[Color, Texture2D](FRHICommandListImmediate& RHICmdList)
{
FRDGBuilder GraphBuilder(RHICmdList);
const FRDGTextureRef RDGRenderTarget = FromRenderTarget2D(GraphBuilder, Texture2D,
TEXT("OutputRenderTarget"));
AddClearRenderTargetPass(GraphBuilder, RDGRenderTarget, Color);
GraphBuilder.Execute();
}
);
}

40.
[beta]
具体例を見てみよう
与えられた RenderTarget2D を単色で塗りつぶすサンプル
void URenderingPracticeLibrary::ClearTexture2D(UTextureRenderTarget2D* Texture2D, const FColor& Color)
{
ENQUEUE_RENDER_COMMAND(ClearTexture2D)(
[Color, Texture2D](FRHICommandListImmediate& RHICmdList)
{
RDG が生成した RHICommand を追加する CommandList を渡してビルダー
FRDGBuilder GraphBuilder(RHICmdList); を作成!
const FRDGTextureRef RDGRenderTarget = FromRenderTarget2D(GraphBuilder, Texture2D,
TEXT("OutputRenderTarget"));
AddClearRenderTargetPass(GraphBuilder, RDGRenderTarget, Color);
GraphBuilder.Execute();

↑ RDG Builder を使った処理本体。RDGを通して組み立てる処理を設計する!
ここで使っているのは RDG 用に追加されたユーティリティ関数。自分で書くのも可

} RDG Builder を実行!
);
}

ここで初めてリソースの確保や RHICommand の追加が行われる。
RDG を通して確保したリソースは、不要になったタイミングで開放する
コマンドが自動追加される。

41.

具体例を見てみよう BP関数として公開して RenderTarget に対して実行すると…… BPで実行 塗りつぶされた! (Widget として配置して確認)

42.

具体例を見てみよう Unreal Insights で RDG Insights を有効にして確認 スコープ → パス → リソース有効期間 → CPUのInsights とは別に、RDG が作成したパス(処理)とリソース のスケジュール履歴が確認できる。

43.

具体例を見てみよう Scene のレンダリングで使われている RDG の Insight も見てみる 超わかりやすい。 (この画像は Epic のスライドから引用)

44.

自分で用意した RenderTarget になら自由自在 いつも見ている Scene のレンダリングではなく、RenderTarget に対してであれば、RenderThread 上で RDG + RHI を使って自 由に描画が行なえる。 実装 間に合わなかった! 自作ピクセルシェーダーで塗る (ノイズ) 単独メッシュをレンダリング

45.

これから RHI 触る人は RDG も使っていこう RHI についての情報を調べると、(そもそも少ないですが)出てくる 情報は RHICommandList を直接触るものが多い。 RDGパス内部などでCommandListを直接操作するのは今でも普通 ですが、リソース準備やパスのセットアップ、シェーダーのバイン ディングなどは RDG で行う形に移行しつつある。 エンジンのユーティリティも RHICommand向けが非推奨になり、 RDGBuilder に変わったりしており、これから触る人注意。 推奨参考資料: https://epicgames.ent.box.com/s/ul1h44ozs0t2850ug0hrohlzm53kxwrz

46.

SceneViewExtension

47.

SceneViewExtension ↑ヤバい

48.

SceneViewExtensionとは? どうしてヤバいのか? SceneViewExtension は、ISceneViewExtension インター フェースを派生することで実装できる、SceneView の拡張機能。 プラグイン、プロジェクト問わず実装可能。

49.

SceneViewExtension でできること 一言でいうと、標準の Scene 描画プロセスに介入できる。 具体的には、 ● View 初期化時の投影行列計算や、View Point 決定を乗っ取 る。 ● Scene 描画のいくつかの地点で Scene 描画に使っている RDGBuilder を取得し、リソース変更やパス追加をする。 などが可能。

50.

SceneViewExtensionの実装方法 - 1 こんな感じで拡張したい virtual メンバを実装したクラスを作 る。 拡張が登録されると、各メンバ関数が決められたタイミングで Scene 描画の処理の中から呼び出されるようになる。 class FExampleSceneViewExtension : public FSceneViewExtensionBase { public: FExampleSceneViewExtension(const FAutoRegister&); virtual ~FExampleSceneViewExtension() override; virtual void SetupViewFamily(FSceneViewFamily& InViewFamily) override; virtual void SetupView(FSceneViewFamily& InViewFamily, FSceneView& InView) override; virtual void PreRenderViewFamily_RenderThread(FRDGBuilder& GraphBuilder, FSceneViewFamily& InViewFamily) override; virtual void SubscribeToPostProcessingPass(EPostProcessingPass Pass, FAfterPassCallbackDelegateArray& InOutPassCallbacks, bool bIsPassEnabled) override; };

51.

SceneViewExtensionの実装方法 - 2 モジュールのスタートアップとかでインスタンス化する。 インスタンスは適当に持っておく。 ExampleSceneViewExtension = FSceneViewExtensions::NewExtension<FExampleSceneViewExtension>(); 完了! NewExtension で登録までやってくれる。 せっかくなので、いくつか面白いメソッドを確認したいのです が、その前に……

52.

Deferred Rendering 復習 Scene View Extension の凄さを理解するために、少しだけ Deferred Rendering について復習。 Deferred Rendering は、リアルタイムレンダリングにおける手 法の一つ。 UEでも、一部モバイルやVRを除く、多くのプラットフォームで は Deferred Rendering が利用されている。

53.

Deferred Rendering 復習 Deferred Rendering は、ピクセルの色決定プロセスを、ジオメ トリ描画とそのライティングの2段階に分割して行う手法。 ● Geometry Pass (UEの BasePass) ● Lighting Pass 一般的には、さらに以下のようなパスを追加して完成させる。 ● Translucency Pass ● Post Processing Pass

54.

Deferred Rendering 復習 (Geometry Pass) GBuffer と呼ばれる描画可能テクスチャに、視点から見たシーン のオブジェクト情報(奥行き、法線、色、ラフネス、etc…)を書き 込む。これが Geometry Pass。UE では Base Pass。 シーン情報 (Mesh, Material) Normal Roughness BaseColor Depth Metallic Specular Geometry Pass

55.

Deferred Rendering 復習 (Lighting Pass) GBuffer とライト情報を合わせることで、元のシーン情報なしにライ ティング済みの画面を計算できる。ライティングコストがシーンのオ ブジェクト数に依存しないので効率的。 + ライト情報 Lighting Pass

56.

Deferred Rendering 復習 (Translucency) GBuffer は1ピクセル = 1オブジェクトの情報しか格納できない。よって、オブ ジェクトが重なる透過を処理できない。Translucency Pass で透過物は追加合成 する。オブジェクトごとに Lighting するうえ、1ピクセルに2回目以上の描画が 発生する(overdraw)ため、ハイコスト。順序を扱うのも難しい。 + 透過物情報 (Mesh, Material) Translucency Pass

57.

Deferred Rendering 復習 (PostProcess) PostProcess(PP) は Deferred Rendering に固有のものではないが、他手法にお ける PP と比較して自由度が高くなる。PP より前のパスでレンダリングした GBuffer 等の情報をフルに活用できるためである。 UE ではアップスケール, Anti-Aliasing, Motion Blur, Bloom, Tonemapping な ど、多様な処理が行われ、画面が完成される。 Post Process Pass Final Color

58.

Deferred Rendering 復習 (大きな流れ) 非常に大まかに、特に UE における Deferred Rendering の流れを示す と、以下のようになる。実際にはもっと多くの各機能のためのパスが存 在するため、恐ろしく単純化したものだが、まず踏まえたい基本のパス 達といえる。 Base Pass Lighting Translucency Post Process Final Color

59.

PreRenderView_RenderThread Parameter: FRDGBuilder&, FSceneView& 毎フレームの RenderThread 開始直後に SceneView ごとに呼ば れる。渡されてくる FRDGBuilder は Scene 描画用に作成された 直後! フレームのレンダリングの頭に好きなパスを挟んだり、リソース を確保しておいて後のパスと共用したりするのに向いている。 ここ Base Pass Lighting Translucency Post Process

60.

PostRenderBasePassDeferred_RenderThread Parameter: FRDGBuilder&, FSceneView&, FRenderTargetBindingSlots&, TRDGUniformBufferRef<FSceneTextureUniformParameters> BasePass の直後に View ごとに呼ばれる。 ここでは View 情報はもちろん、SceneColor, 各種GBuffer, DepthStencil 等の RenderTarget を読み込み/書き込み可能。 BasePass 後、Lighting 前はポストプロセスでは介入できないため、これが できるだけで拡張性が段違いになる。 ここ Base Pass Lighting Translucency Post Process

61.

PrePostProcessPass_RenderThread Parameter: FRDGBuilder&, const FSceneView&, FPostProcessingInputs& PostProcess の直前に呼ばれる。 パラメータとして、FPostProcessingInputs が書き換え可能な参照とし て渡ってくるのが特徴。 すでに Lighting を受けた SceneColor 等がある状態で、これからポス トプロセスの入力として入っていくバッファを変更できる場所。 ここ Base Pass Lighting Translucency Post Process

62.

PostRenderView_RenderThread Parameter: FRDGBuilder& GraphBuilder, FSceneView& InView すべてのレンダリングが終了した後に呼ばれる。 FSceneView& を通して描画リソースにアクセス可能。 インゲーム用パスの追加のほか、デバッグ描画パス、描画情報の 収集等の追加に向いている。 ここ Base Pass Lighting Translucency Post Process

63.

SubscribeToPostProcessingPass (概要) Parameter: EPostProcessingPass, FAfterPassCallbackDelegateArray&, bool これは少し毛色が違う。PostProcess を Material ではなく C++ と シェーダー で書く ための登録ができる。 EPostProcessingPass としてポスプロの挿 入位置が渡されてくると同時に、その位置で 実行したいコールバックを登録できる。 EPostProcessingPass { SSRInput, MotionBlur, Tonemap, FXAA, VisualizeDepthOfField }; ポスプロ位置の種類 ここの内部 Base Pass Lighting Translucency Post Process

64.

復習: Post Process Material と Blendable Location UE の Post Process Material は、Material 機能を使って画面全体に対する変更 を加えるパスを追加する仕組み。 よく「最後の調整のところ」と言われるが、Post Process Material が描画パス として挿入される位置には種類がある。この場所のことを UE では Blendable Location と呼んでいる。 すべて Post Process Pass 内だが、場所によって入力元・出力先が異なるの で、できることが違う。

65.

SubscribeToPostProcessingPass Parameter: EPostProcessingPass, FAfterPassCallbackDelegateArray&, bool SubscribeToPostProcessingPass の挿入位置も、Material の Blenadable Location と対応している。 C++ / HLSL の機能をフル活用したポスプロが書ける。 例: MotionBlur 時に処理を入れたい場合 static FScreenPassTexture OnExecutePostProcessPassCallback(FRDGBuilder& GraphBuilder, const FSceneView& View, const FPostProcessMaterialInputs& Inputs) { // 何もしないでそのまま返す。ここで返すテクスチャが次の入力になる。 return Inputs.Textures[0]; } void FExampleSceneViewExtension::SubscribeToPostProcessingPass(/* 省略 */) { if (Pass == EPostProcessingPass::MotionBlur) { InOutPassCallbacks.Add(FAfterPassCallbackDelegate::CreateStatic(&OnExecutePostProcessPassCallback)); } }

66.

具体例 PostRenderBasePassDeferred_RenderThread で GBuffer 書き換えてみた BasePass 後、Lighting 前に GBuffer の Metalic をすべて 1.0 で埋めてしまうパスを追加してみ た図。 元のマテリアルはきちんと値を出 しているが、追加したパスで上書 きされて超メタリック空間になっ ている。

67.

具体例 PostRenderBasePassDeferred_RenderThread で GBuffer 書き換えてみた もちろん、アウトライン生成な ど、需要がありそうな(?)ことも 一通りできる。 このサンプルが地味なのは試したのが2時間前く らいだからで……許してください

68.

SceneViewExtension ● Scene レンダリングのあちこちにパスを追加できてしまうので わりと何でもできる。可能性は無限大。 ● エンジン改造不要。プラグインやプロジェクトコードで対応可。 ● GBufferを追加したり、既にあるパスの内部フローを直接的に書 き換えることは Extension からは難しそう。 ○ 後者については実行前の RDGBuilder を書き換えることですこし可能かもし れないが……

69.

今日のまとめ

70.

今日のまとめ UE は高品質な画面を高速にあらゆる場所で描画するた め、背後に巨大なグラフィックスレイヤを持っている。 直接触ることができれば、そのレイヤの力を自分のコンテ ンツに取り入れることもできる! どんどん拡張性も上がっているので、今後はさらに期待。