UnityのUniversal Render Pipeline (URP) において、カスタムの Scriptable Render Feature を追加し、描画タイミング(RenderPassEvent)を AfterRenderingOpaque(不透明オブジェクトの描画後)などに設定した際、描画したいオブジェクトが画面に全く表示されない問題が発生することがあります。エラーが出力されないため原因特定が難しい不具合です。

本記事では、この描画が行われない原因である「レンダーターゲットバッファの見失い」を解消し、確実にカスタム描画を実行するための解決方法を解説します。

初心者向け:この問題を現実で例えると?

このトラブルを現実のレストランに例えてみましょう。

レストランのキッチン(URPのレンダラー)では、シェフが料理(描画データ)を作っています。通常であれば、出来上がった料理は指定されたテーブル(カメラのカラーターゲットバッファ)へ運ばれます。

しかし、Render Featureでバインド処理が抜けている状態は、「料理は完成したけれど、どのテーブルに運べばいいか書かれた伝票が紛失している状態」と同じです。料理は配膳台の隅に置き去りにされ、お客さん(画面)の元には届きません。これが「エラーは出ないのに画面には何も映らない」現象の正体です。料理に「このテーブル(バッファ)へ運んでください」と明確な指示書(ConfigureTarget)を添えてあげる必要があります。

不具合の症状と具体的な現象

このバグが発生した際、以下のような症状が見られます。

  • シーンビューやゲームビューで、カスタムパスを通して描画されるべきオブジェクトが完全に透明(描画されない)状態になる。
  • Frame Debuggerで描画命令(Draw Call)を確認すると、処理自体は実行されているが、描画先が Null もしくは意図しないバッファになっており、最終画面に反映されていない。
  • RenderPassEvent を変更すると突然描画されることがあるが、描画順序が狂ってしまい意図した見た目にならない。

想定される原因:なぜ描画先を見失うのか?

URPは、描画パフォーマンス最適化のためにレンダーターゲットを動的に切り替えています。特に不透明オブジェクトの描画直後などのイベント境界では、URP自身がポストプロセスへの橋渡しのために一時的にレンダーバッファを切り離します。

この切り替えの際、カスタムの ScriptableRenderPass が「現在アクティブなカメラのレンダーターゲットがどこであるか」を把握できていないと、無効なバッファや空の領域に対して描画命令を実行してしまいます。これが原因で、描画しているにもかかわらず最終画面に反映されず消え去ってしまうのです。

具体的な解決方法とアプローチ

この問題を解決するには、以下の2つの実装を行います。

1. RenderPassEvent の同期調整

レンダーパスの実行タイミングを適切に設定します。不透明オブジェクトの描画直後に処理を行いたい場合は、コンストラクタでイベントを指定します。

public class CustomRenderPass : ScriptableRenderPass
{
    public CustomRenderPass()
    {
        this.renderPassEvent = RenderPassEvent.AfterRenderingOpaque;
    }
}

2. ConfigureTarget によるターゲットの明示的再バインド

レンダーパスが実行される直前の OnCameraSetup メソッド内で、カメラのカラーターゲットとデプスターゲットを明示的に取得し、描画先として再設定します。

using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Universal;

public class CustomRenderPass : ScriptableRenderPass
{
    public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
    {
        var renderer = renderingData.cameraData.renderer;
        // ターゲットを明示的に指定して ConfigureTarget を呼び出す
        ConfigureTarget(renderer.cameraColorTargetHandle, renderer.cameraDepthTargetHandle);
    }

    public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
    {
        CommandBuffer cmd = CommandBufferPool.Get("CustomRenderPass");
        using (new ProfilingScope(cmd, new ProfilingSampler("Draw Custom Objects")))
        {
            // 描画処理をここに行う
        }
        context.ExecuteCommandBuffer(cmd);
        CommandBufferPool.Release(cmd);
    }
}

実務で役立つ確認チェックリスト

カスタムレンダーフィーチャーを導入した際、描画が正常に行われない場合に確認すべき実務チェックリストです。

確認項目 確認方法・対策
URP Assetへの登録 使用しているURP Rendererデータに、Custom Render Featureがリストに追加されているか。
Layerの不一致 描画対象オブジェクトのLayerが、描画設定フィルターで除外されていないか。
Frame Debugger Frame Debuggerを開き、自分自身の描画パスが実行されているか確認する。

まとめ

URPのCustom Render Featureを用いた描画処理は、タイミングのズレやバインド漏れが原因でサイレントに描画が消失する問題が頻発します。描画先を ConfigureTarget で常に明示的に指定する習慣をつけることで、パイプラインの途中で迷子になる描画データを防ぎ、安定したカスタムエフェクトを構築することができます。