7.5K Views
July 11, 24
スライド概要
【U/Day Tokyo 2024】
U/Day Tokyo 2024では 日本のゲームクリエイター、エンジニア、アーティストのために、Unity 6 に関する最新情報や開発ロードマップの紹介、グラフィックスやUI、DOTS、最適化などの各種技術の解説、Unity Muse や Unity Cloud といった Unity の最新製品・サービスのライブデモ、ゲームアプリのユーザー獲得やマネタイズの最新トレンドなどを、Unity Japan や Unity 本社のスタッフが講演します。
【講演内容】
・タイトル:URP17へのアップグレードとRender Graphの活用方法
・講演者:ブーシェ ロビン晃(パートナーエンジニア)
・講演内容:Unity 6 Previewがリリースされ、Universal Render Pipeline (URP) はバージョン17になりました。URP17では大きな変更としてRender Graph APIが導入されています。このセッションでは、URP17へのアップグレードガイドと共に、Render Graphを活用するためのTipsを解説していきます。
リアルタイム3Dコンテンツを制作・運用するための世界的にリードするプラットフォームである「Unity」の日本国内における販売、サポート、コミュニティ活動、研究開発、教育支援を行っています。ゲーム開発者からアーティスト、建築家、自動車デザイナー、映画製作者など、さまざまなクリエイターがUnityを使い想像力を発揮しています。
URP 17アップグレードと Render Graphの活⽤⽅法
Presentation Title ブーシェ ロビン晃 パートナーエンジニア
新機能の紹介 GPU Resident Drawer Agenda Render Graph Render Graphの基本 Render Passを実装する Render Graph Viewer その他のTips
新機能の紹介
Adaptive Probe Volume ● Light Probeをシーンの形状に合わせて ⾃動配置する ● Light Probe Groupはオブジェクトベース のライティングだが、Probe Volumeは ピクセルベースとなり、より⾃然な ライティングを実現 参考マニュアル ● https://docs.unity3d.com/Packages/[email protected]/man ual/probevolumes.html ● [紹介動画] https://youtu.be/4eIAWo-Gmiw
HDR出⼒ ● HDRに対応しているディスプレイで HDR出⼒が可能に ● ● モバイル対応の追加 ○ iOS 16+ ○ Android 9+ (デバイス依存) Rendering DebuggerにHDR確認機能を 追加 参考マニュアル ● https://blog.unity.com/engine-platform/cross-platform-hdr-display-support ● https://docs.unity3d.com/Packages/[email protected]/man ual/post-processing/hdr-output.html
Screen Space Lens Flare ● ポストプロセスによるLens Flare ● 従来のLens Flareコンポーネントは 個別ライトに対するエフェクト ● Screen Space Lens Flareはspecularや emissionなど、画⾯上のすべての光る 箇所に効果がかかる 参考マニュアル ● https://docs.unity3d.com/Packages/[email protected]/man ual/shared/lens-flare/post-processing-screen-space-lens-flare.html ● [紹介動画] https://youtu.be/-6zbFTBMDmU
Soft Shadowクオリティレベル ● Soft Shadowにクオリティレベル設定が 追加 ● ライトごとのオーバーライドも可能 参考マニュアル ● https://docs.unity3d.com/Packages/[email protected]/man ual/universalrp-asset.html#shadows
Object Motion Blur ● カメラの動き以外に、オブジェクトのみ の動きにもMotion Blurを適⽤できる ● Motion Blurのモードを「Camera」と 「Camera and Objects」から選べる 参考マニュアル ● https://docs.unity3d.com/Packages/[email protected]/manu al/Post-Processing-Motion-Blur.html
カスタムポストプロセス ● カスタムポストプロセスを実装する スクリプトテンプレートを追加 ● Volumeコンポーネント及びRenderer Featureのスクリプトが⽣成される ● Volumeに準ずるカスタムポストプロセス の実装に有⽤ ※ URP標準のポストプロセスとは独⽴したVolume‧Render Passになります
GPU Resident Drawer
GPU Resident Drawerとは ● GPU上で効率的なMeshのインスタンス処 理を⾏うシステム。 BatchRendererGroup APIを使⽤する ● 主に⼤量のMeshRendererを描画する際の CPU負荷 (ドローコール) を軽減する ● URPアセットから有効にできる (デフォルトはOFF) 参考マニュアル ● https://docs.unity3d.com/Packages/[email protected]/man ual/gpu-resident-drawer.html ● https://forum.unity.com/threads/gpu-driven-rendering-in-unity.1502702/
GPU Resident Drawerの注意点 ● Forward+ Rendererのみ対応 ● ComputeがサポートされているGraphics APIのみ対応 ● MeshRendererのみ。SkinnedMeshRenderer‧パーティクルなどは対象外 ● MaterialPropertyBlockを使⽤しているオブジェクトは対象外 ● リアルタイムGIの影響を受ける‧与えるオブジェクトは対象外 ● GPU処理が増える ○ ● 既にGPU負荷が⾼い状態だとパフォーマンスが下がる場合も マテリアルのシェーダーがDOTS Instancingに対応している必要がある
シェーダーのDOTS Instancing対応 DOTS_INSTANCING_ONキーワードを追加 #pragma multi_compile _ DOTS_INSTANCING_ON プロパティをDOTS Instancedにする // プロパティ宣言 UNITY_DOTS_INSTANCING_START(MaterialPropertyMetadata) UNITY_DOTS_INSTANCED_PROP(half4, _BaseColor) UNITY_DOTS_INSTANCING_END(MaterialPropertyMetadata) // プロパティアクセス UNITY_ACCESS_DOTS_INSTANCED_PROP(half4, _BaseColor) 参考マニュアル ● https://docs.unity3d.com/6000.0/Documentation/Manual/dots-instancing-shaders.html URP標準シェーダーもご参照ください
Render Graph
Unity 6より、URPにRender Graphが 導⼊されました 参考マニュアル ● https://docs.unity3d.com/Packages/[email protected]/man ual/render-graph.html
Render Graphの基本
Render Graphとは レンダリングパイプラインで使うリソースを効率的に⾃動管理するシステム。 Render Passが使⽤するリソース (Render Textureなど) をあらかじめ宣⾔することに より、Render Graphが適切にリソースを管理する。 無駄なリソースの確保を抑え、GPUに送られるデータ量を減らすことにより、描画処理 を最適化し、パフォーマンス向上を図る。
Render Graphの最適化⼿法 リソース管理の⾃動化 ● Render Textureなどのリソースを⾃分でAllocate/Disposeする必要がない 使⽤メモリの最適化 ● リソース重複によるメモリの無駄を抑える ● 例: 同じ解像度‧フォーマットのRender Textureを複数宣⾔した場合、 ひとつのリソースに集約する
Render Graphの最適化⼿法 Pass Merging ● リソースのRead/Writeアクセスを元に、Render Passの依存関係を洗い出す ● 依存関係と実⾏順に応じて複数のRender PassをひとつのNative Render Passに マージする ● Native Render Pass対応が必要 ○ Vulkan‧Metal‧DX12が対象 Pass Culling ● Render Passの出⼒が他のパスから参照されない場合、Render Passを カリングする (実⾏しない)
Pass Merging URPデフォルトのパス実⾏順 Draw Objects (Opaque) Draw Skybox Draw Objects (Transparent) Write Write Write Camera Color Render Target Post Process Read
Pass Merging URPデフォルトのパス実⾏順 Draw Objects (Opaque) Draw Skybox Draw Objects (Transparent) Write Write Write Camera Color Render Target オブジェクト描画パスがCamera ColorにWrite Post Process Read
Pass Merging URPデフォルトのパス実⾏順 Draw Objects (Opaque) Draw Skybox Draw Objects (Transparent) Write Write Write Camera Color Render Target Post ProcessパスがCamera ColorからRead Post Process Read
Pass Merging 互いに依存関係がないため、ひとつのNative Render Passにマージできる Draw Objects (Opaque) Draw Skybox Draw Objects (Transparent) Native Render Pass Write Camera Color Render Target Post Process Read
Pass Merging 前パスのRender Targetを読み込む依存関係があるため、マージできない Draw Objects (Opaque) Draw Skybox Draw Objects (Transparent) Native Render Pass Write Camera Color Render Target Post Process Read
Pass Culling カスタムRender Targetに書き込んでいるカスタムRender Passの例 カスタム Render Pass Draw Objects Write Write カスタムRender Target Post Process Read Camera Color Render Target
Pass Culling Render Targetが他のパスに参照されていないため、カリングされる (実⾏されない) CULL Draw Objects Write カスタムRender Target Write Post Process Read Camera Color Render Target
Render Graphの基本‧まとめ ● Render Passのリソースが⾃動管理される ● リソースの使⽤メモリが最適化される ● Pass MergingとPass Cullingにより、Render Passの実⾏が最適化される ● メモリ使⽤量が減り、パフォーマンスが向上する ● Native Render Pass対応Graphics APIが最も恩恵を受ける (Vulkan‧Metal‧DX12) ※ 新規プロジェクトではデフォルトでRender Graphが有効になっています
Render Passを実装する
リソース宣⾔ Render Graphではリソースが⾃動的に管理されるため、Render Passで Render Textureなどのリソースを直接扱わない 代わりに確保したいリソースに応じたResource Handleを宣⾔する
リソース宣⾔ Resource Handle⼀覧 TextureHandle ● Texture‧Render Texture (RTHandle) ⽤のHandle RendererListHandle ● オブジェクト描画に使うRendererList⽤のHandle BufferHandle ● Computeシェーダーで使うGraphicsBuffer⽤のHandle
Render Passの分類 Render GraphではPass Mergingを⾏うため、Render Passを⽤途別に細分化している Render Passの分類 ● RasterPass ● ComputePass ● UnsafePass 分類されたRender Passは⽤途があり、できることに制限がある
Render Passの分類 RasterPass ● 指定したRender Targetに描画を⾏うRender Pass ● RasterCommandBufferを使って実装する ○ 描画⽤Command Buffer。Computeはできない ● Blitやオブジェクトの描画に使う ● ひとつのRender Targetにしか書き出しができない ○ 複数のRender Targetに書き出したい場合、複数のRasterPassに分割する 必要がある
Render Passの分類 ComputePass ● Computeシェーダー⽤のRender Pass ● ComputeCommandBufferを使って実装する ○ ● Compute⽤Command Buffer。描画はできない Render Targetへの描画はできない
Render Passの分類 UnsafePass ● 制限事項がないRender Pass ● 通常Command Bufferを使い、⾃由に処理を記述できる ● Pass Merging対象外 ⽤途は? ● Pass Mergingできないとわかっている場合に実装を簡易化する ● 旧バージョンで実装したRender Passをそのまま移植できるため、 Render Graphへ移⾏するファーストステップにも便利
APIの簡易化 煩雑になっていたScriptableRenderPass APIは軒並みObsoleteに ● OnCameraSetup ● Configure ● ConfigureTarget ● Execute ● OnFinishCameraStackRendering ● etc... 実装するメソッドをRecordRenderGraphのひとつのみに集約
RecordRenderGraphの実装 RecordRenderGraphでやること 1. Render Passで使⽤するリソースを宣⾔する (Resource Handle) 2. 各リソースのアクセス (Read/Write) を指定する 3. パス実⾏メソッドを実装する 4. パス実⾏メソッドを登録する
Render Passのコード例
Render Passのコード例 Camera ColorをRender TextureにBlitする例 // RecordRenderGraphメソッドを実装 public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData) { // Render Targetへの描画を行うため、 // RasterPassを使用 (RenderGraphBuilderの取得) using ( IRasterRenderGraphBuilder builder = renderGraph.AddRasterRenderPass("MyBlitPass", out PassData passData) ) { /* 実装 */ } }
Render Passのコード例
使⽤リソース (Resource Handle) の宣⾔
using (IRasterRenderGraphBuilder builder =
renderGraph.AddRasterRenderPass("MyBlitPass", out PassData passData)) {
// URPの共通リソースへのアクセサより、現在の Camera ColorのTextureHandleを取得
UniversalResourceData resourceData = frameData.Get<UniversalResourceData>();
TextureHandle cameraColorTextureHandle = resourceData.activeColorTexture;
// 書き込み先の Render TextureのTextureHandle宣言
TextureHandle targetTextureHandle = UniversalRenderer.CreateRenderGraphTexture("_MyRenderTarget");
Render Passのコード例 リソースのアクセス指定 using (IRasterRenderGraphBuilder builder = renderGraph.AddRasterRenderPass("MyBlitPass", out PassData passData)) { /* ... */ // Camera Colorから読み込むため、 Readアクセスを指定 builder.UseTexture(cameraColorTextureHandle, AccessFlags.Read); // カスタム Render TargetをRasterPassのRender Targetに指定 (= Writeアクセス指定 ) // CommandBuffer.SetRenderTargetと同等 builder.SetRenderAttachment(targetTextureHandle, AccessFlags.Write);
Render Passのコード例 パス実⾏に必要なPassData指定 private class PassData { public TextureHandle sourceTextureHandle; // Blit sourceのTextureHandle (Camera Color) public Material material; // Blitに使うマテリアル } using (IRasterRenderGraphBuilder builder = renderGraph.AddRasterRenderPass("MyBlitPass", out PassData passData)) { /* ... */ // PassDataをセット passData.sourceTextureHandle = cameraColorTextureHandle; passData.material = m_blitMaterial;
Render Passのコード例 パス実⾏メソッドを実装 // パス (RasterPass) 実行メソッド private static void ExecutePass(PassData passData, RasterGraphContext graphContext) { // RasterPass専用のRasterCommandBuffer RasterCommandBuffer cmd = graphContext.cmd; // PassDataを使い、 Blitを実行 Blitter.BlitTexture(cmd, passData.sourceTextureHandle, passData.material); }
Render Passのコード例
パス実⾏メソッドを登録
using (IRasterRenderGraphBuilder builder =
renderGraph.AddRasterRenderPass("MyBlitPass", out PassData passData)) {
/* ... */
// SetRenderFuncでパス実行メソッドを指定する (ExecutePass)
builder.SetRenderFunc(
(PassData passData, RasterGraphContext graphContext) => ExecutePass(passData, graphContext)
);
}
サンプルプロジェクトレポジトリ Render GraphでのRender Passサンプルを下記で公開しているので、ご参照ください ● https://github.com/robin-boucher/URPRendererFeatureExample6 ※ 公式サンプルも Package Managerから インポートできます
Render Graph Viewer
Render Passとリソースを ⼀覧することができる エディターツール 参考マニュアル ● https://docs.unity3d.com/Packages/[email protected]/man ual/render-graph-viewer-reference.html
Render Pass⼀覧 Render Pass実⾏順
Render Pass⼀覧 カリングされたRender Pass マージされたRender Pass
Render Pass⼀覧 Render Passのスクリプトを開く ショートカットボタン
リソース⼀覧 リソース⼀覧
リソース⼀覧 Read Write Global Texture Frame Buffer Fetch (後述) リソースライフタイム
Render Pass詳細 前後のRender Passと マージできない要因 マージされている Render Pass 使⽤リソースの Load/Storeアクション
その他のTips
Pass Cullingの無効化 ユースケース: Render PassでカスタムRender Targetに描画し、後のパスで Global Textureとしてシェーダーでサンプリングできるようにする カスタムRender Pass 1 カスタムRender Pass 2 SetGlobalTexture Global Textureを シェーダーで カスタムRender Target サンプリング シェーダーからのサンプリングだけだと「Render Targetが参照されている」 と⾒なされず、Render Passがカリングされてしまう
Pass Cullingの無効化 AllowPassCullingをfalseにすることでPass Cullingを無効化できる // Render TargetをGlobal Textureにする builder.SetGlobalTextureAfterPass(targetTextureHandle, renderTargetId); // AllowPassCulling = falseでPass Cullingを無効化 builder.AllowPassCulling(false);
Render Textureをカメラ間で保持 ユースケース: Base Cameraで書き出したRender Textureを Overlay Cameraで参照する Base Camera Overlay Camera Write Read Render Target TextureHandleをカメラを跨いで共有する⽅法がない
Render Textureをカメラ間で保持 ImportTextureを使い、外部で管理するRTHandleからTextureHandleを⽣成する private RTHandle m_RTHandle; // 外部で管理する RTHandle public void SetExternalRTHandle(RTHandle rtHandle) { m_RTHandle = rtHandle; } /* ... */ TextureHandle targetTextureHandle = renderGraph.ImportTexture(m_RTHandle); ※ RTHandleは外部管理するため、Allocate/Disposeは⾃分で⾏う
Frame Buffer Fetch Frame Buffer Fetch API ● フレームバッファからフラグメントカラーを直接読み込むことができる ● シェーダーからFrame Buffer Fetchを⾏う ● Frame Buffer Fetchを活⽤すると、通常だと分かれるRender Passが マージされるなどの最適化が可能になる ※ Native Render Pass対応が必要 ● Vulkan‧Metal‧DX12が対象
Frame Buffer Fetch シェーダーからFrame Buffer Fetchを⾏う // index 0のフレームバッファ入力を宣言 FRAMEBUFFER_INPUT_X_HALF(0); (ここでは half precision) // フラグメントシェーダー half4 Frag(Varyings input) : SV_Target { // フレームバッファから読み込み half4 color = LOAD_FRAMEBUFFER_X_INPUT(0, input.positionCS.xy); return color; }
Frame Buffer Fetch Blit処理のPass Merging例 通常 マージなし Frame Buffer Fetch ( マージされる )
そして最後に‧‧‧Compatibility Mode Render Graphを無効にするオプション ● Render Graph対応をせず、プロジェクトをUnity 6にバージョンアップできる ○ ● 既存プロジェクトはデフォルトでCompatibility Modeが有効になる 旧ScriptableRenderPass APIが使⽤可能 ただし、将来Deprecateされる可能性があるため なるべくRender Graphへの移⾏を推奨しています!
Thank you