CORETECH ENGINEER BLOG

株式会社サイバーエージェント SGEコア技術本部 技術ブログ

【Unity6.3新機能】RenderGraph関連の新機能・変更点

こんにちは、SGEコア技術本部所属のグラフィックスエンジニア チャン ユービンです。

前回の記事ではUnity 6.3で新たに追加されたShaderBuildSettingsについて紹介しました。

【Unity 6.3新機能】ShaderBuildSettingsでソースコードを変更せずにShaderバリアントを最適化する

今回はUnity 6.3におけるRenderGraph関連の新機能と変更点をいくつピックアップして紹介します。

RenderGraphについてまだ詳しくない方は、過去のRenderGraph関連記事をご参照ください:

本記事の執筆時点で使用したUnityバージョンは6000.3.2f1です。

目次

Compatibility Modeがデフォルトで非表示に

Unity 6.3から、旧バージョンからのアップグレードや新規プロジェクト作成時にRenderGraphがデフォルトで使用されるようになりました。従来のCompatibility Modeオプションは、Graphics設定から非表示になっています。

Compatibility Mode非表示によるメリット

  • イテレーション速度の向上:メンテナンスが必要なコードパスが減り、コンパイル速度が向上し、カスタマイズ作業が簡素化される
  • ビルドサイズの削減URPランタイムアセンブリが1MB未満となり、約8〜10%のサイズ削減が実現
  • コード構造の明確化:非RenderGraphのコードパスが明確に分離される

Unity 6.3でCompatibility Modeを有効にする方法

Compatibility Modeがまだ必要な場合(例:ScriptableRenderPassの移行が未完了)、以下の方法で有効化できます:

  1. PlayerSettingsScripting Define SymbolsURP_COMPATIBILITY_MODEを追加
  2. Graphics設定のURPページ内のRenderGraphセクションにCompatibility Mode (Render Graph Disabled)オプションが表示されるので、チェックを入れて有効化

⚠️ 注意:Unity公式は、RenderGraphを使用しないレンダリングパスの開発・改善を行わないことを明言しており、Compatibility Modeは将来のバージョンで削除される予定です。早めの移行をお勧めします。

参考:Render Graph Updates in Unity 6.3

RenderGraphViewerの新機能

Unity 6.3ではRenderGraphViewerに以下の機能が追加されました:

  • リアルタイム更新機能
    • 自動更新/一時停止を選ぶことができる
  • バイス接続によるリアルタイム監視
    • 実機上でのRenderGraphの動作を分析可能になる
  • Load/Store動作の可視化
    • リソースのセルに新しくLoad/Storeアイコンが追加され、動作を把握しやすくなった

Load/Storeアイコンの色について

左上にLoad Actionが表示される:
緑:Load
青:Clear
グレー:Don't Care

右下にStore Actionが表示される:
赤:Store
グレー:Don't Care

Load/Store表記のないセルは、以下のいずれかに該当します:

  • 該当リソースがそのPassAttachmentとして使用されていない
  • 該当PassUnsafe Passであり、Load/Store情報が記録されていない

BlitPassCopyPassの変更点

Unity 6.3ではRenderGraphAddBlitPassAddCopyPassに以下の変更が加えられました:

  • IBaseRenderGraphBuilderを返すことで、Pass動作をさらにカスタマイズ可能に
  • AddBlitPass内部でFrameBufferFetchが使用可能かを判定し、可能であればAddCopyPassを呼び出してFrameBufferFetchによるパフォーマンス向上を実現
    • ただし、一部の古い端末ではFrameBufferFetchに互換性の問題がある可能性あり

ReturnBuilderパラメータ

AddBlitPassAddCopyPassでは、returnBuilder: trueパラメータを指定することでIBaseRenderGraphBuilderインターフェースを取得し、レンダリングPassの動作をさらにカスタマイズできるようになりました:

// Blitパラメータを作成
var blitParams = new RenderGraphUtils.BlitMaterialParameters(sourceTexture, destinationTexture, blitMaterial, passIndex);

// returnBuilderでBuilderインターフェースを取得
using (var builder = renderGraph.AddBlitPass(blitParams, "My Blit Pass", returnBuilder: true))
{
    // ここでbuilderを使ってBlitPassをカスタマイズ
    // 例:
    builder.UseRendererList(...);
    builder.UseGlobalTexture(...);
    builder.UseBuffer(...);
}

AddBlitPassの自動最適化

AddBlitPassを呼び出した際、以下のすべての条件を満たす場合、UnityはFrameBufferFetch最適化を活用するために自動的にAddCopyPassに切り替えます:

  1. スケールがデフォルト値scale == Vector2.one(1:1コピー、スケーリングなし)
  2. オフセットがデフォルト値offset == Vector2.zero
  3. 単一スライスnumSlices == 1
  4. 単一MipレベルnumMips == 1
  5. ターゲットが深度テクスチャでない:出力先が深度フォーマットでないこと
  6. CanAddCopyPassの検証をパス
    • ソースとターゲットの両テクスチャが有効
    • MSAAサンプル数が同一
    • 幅、高さ、深度が同一
    • ソースとターゲットの両方が深度フォーマットでない
    • MSAAテクスチャの場合、プラットフォームが関連するShader機能をサポート

つまり、AddCopyPassは1:1の正確なコピーのみ実行可能で、スケーリングやテクスチャフィルタリングには対応していません。この制限により、Tile-Based GPU上でFrameBufferFetchを活用した最適なパフォーマンスが実現できます。

FrameBufferFetchの仕組み

  • レンダリングPassがビデオメモリではなく、GPUのオンチップメモリからフレームデータを読み取ることが可能
  • テクスチャをオンチップメモリとビデオメモリ間でコピーする必要がなくなり、メモリ帯域幅の消費を削減
  • TBDR(Tile-Based Deferred Rendering)を採用したモバイルデバイスで顕著なパフォーマンス向上
  • URPフレームバッファへの書き込みと読み取りを行うレンダリングPassを自動的にマージ

FrameBufferFetchの互換性

以下のグラフィックスAPIのみサポート:

  • Vulkan
  • Metal

非対応のAPIOpenGLDirectXなど)では、Unityは自動的に通常のテクスチャコピー方式にフォールバックします。

⚠️ 注意:一部のAndroidバイスFrameBufferFetchの互換性問題あり

一部の古いAndroidバイス(Pixel 4aなどAdrenoGPUを搭載した端末)では、FrameBufferFetch使用時に画面が真っ黒になる、または描画が乱れることがあります。この問題は特定のGPUドライバに起因しており、Unity側での修正は困難な可能性があります(ディスカッションリンク

対処法:特定のデバイスで表示異常が発生した場合、AddBlitPassの使用を避けることを推奨します(FrameBufferFetchを使用するAddCopyPassに自動切り替えされる可能性があるため)。代わりにAddRasterRenderPassで独自のBlitロジックを実装し、FrameBufferFetch最適化を回避してください。

RenderPass内でRenderTargetBackBufferに切り替え可能に

Unity 6.3では、RenderPass内でレンダリングターゲットをBackBufferに切り替える機能が追加されました。

  • UniversalResourceData.SwitchActiveTexturesToBackbuffer()を呼び出すことで、以降のレンダリングターゲットをBackBufferに切り替え可能
  • 切り替え後、URPレンダリング終了時にBlitToBackBuffer Passを作成しなくなり、Blit処理を1回省略できる

切り替え方法

カスタムRenderPassRecordRenderGraph内でUniversalResourceData.SwitchActiveTexturesToBackbuffer()を呼び出します:

var resourceData = frameData.Get<UniversalResourceData>();
resourceData.SwitchActiveTexturesToBackbuffer();

呼び出し後の動作

  • activeColorTextureactiveDepthTextureBackBufferColorBackBufferDepthを返す
  • 以降のレンダリングはすべてBackBufferをターゲットとし、URPレンダリング終了時にBlitToBackBuffer Passを作成しない

関連プロパティ

  • activeColorTexture - 現在アクティブなカラーターゲット。切り替え後はBackBufferColor
  • activeDepthTexture - 現在アクティブな深度ターゲット。切り替え後はBackBufferDepth
  • isActiveTargetBackBuffer - 現在のレンダリングターゲットがBackBufferかどうかを示すフラグ

注意事項

  • BackBufferは入力リソースとして使用できないため、レンダリング処理の序盤でBackBufferに切り替えるべきではありません。レンダリングフローの最終段階で呼び出すことを推奨します
  • BackBufferへの出力時は、プラットフォームに応じてUV座標の反転が必要な場合があります。反転の要否はSystemInfo.graphicsUVStartsAtTopプロパティで確認できます

使用例:カスタムFXAA処理

カスタムFXAAポストプロセスを例に、SwitchActiveTexturesToBackbuffer()を使用するメリットを説明します。

従来の処理フロー

CameraColor → [FXAA処理] → FXAABuffer → [Blit] → CameraColor → [URPFinalBlit] → BackBuffer

合計3回のBlit処理が必要でした。

Unity 6.0以降で可能な処理フロー

CameraColor → [FXAA処理] → FXAABuffer → [URPFinalBlit] → BackBuffer

CameraColorを直接FXAABufferに置き換えることでBlit処理を1回削減できますが、FXAABufferという中間テクスチャが必要で、URPFinal Blit Passも引き続き作成されます。

Unity 6.3でBackBuffer切り替えを使用した処理フロー

CameraColor → [FXAA処理] → BackBuffer

FXAA結果を直接BackBufferに出力することで、FXAABuffer中間テクスチャが不要になり、URPFinal Blit Passも作成されなくなります。

コード例

public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
{
    var resourceData = frameData.Get<UniversalResourceData>();

    // まずCameraColorを取得
    var source = resourceData.activeColorTexture;

    // レンダリングターゲットをBackBufferに切り替え
    resourceData.SwitchActiveTexturesToBackbuffer();

    // この時点でactiveColorTextureはBackBufferになっている
    var destination = resourceData.activeColorTexture;  // resourceData.backBufferColorも使用可

    // 注意:プラットフォームによってはUV座標の反転が必要
    var scale = SystemInfo.graphicsUVStartsAtTop
                ? new Vector2(1, -1)
                : new Vector2(1, 1);
    var offset = SystemInfo.graphicsUVStartsAtTop
                ? new Vector2(0, 1)
                : new Vector2(0, 0);

    // AddBlitPassでFXAA処理結果を直接BackBufferに出力
    var blitParams = new RenderGraphUtils.BlitMaterialParameters(source, destination, scale, offset, fxaaMaterial, 0);
    renderGraph.AddBlitPass(blitParams, "Custom FXAA Pass");

    // BackBufferに切り替え済みのため、URPはFinal Blit Passを作成しない
}

効果の比較

Unity 6.0では、FinalBlitPassが常に作成されていました:

Unity 6.3でBackBuffer切り替えを使用すると、1回のBlit処理でFXAA処理が完了しBackBufferに直接出力されます:

この方法により、不要なBlit処理を削減し、レンダリングパフォーマンスを向上させることができます。

まとめ

今回紹介したことを簡単にまとめてみると以下になります:

  • Compatibility Modeの非表示化コンパイル速度の向上、ビルドサイズの削減、コード構造の明確化
  • RenderGraphViewerの強化:デバイス接続対応、Load/Store動作の可視化
  • RenderGraphAddBlitPass/AddCopyPassの変更Builderによるカスタマイズ対応、自動FrameBufferFetch最適化
  • BackBufferへの切り替えBlit回数の削減、GPU帯域幅消費の低減

今後も引き続きUnityの便利機能を紹介していきますので、どうぞお楽しみに!