夜風のMixedReality

xRと出会って変わった人生と出会った技術を書き残すためのGeekなHoloRangerの居場所

URPのCustomRendererFeatureを使用してポストプロセッシングを実装する その①

本日はUnity調査枠です。

UniversalRenderPipeline(URP)ではRenderer Featurerを使用してカメラのレンダリングの処理を追加することでポストプロセスを実装します。

筆者自身RendererFeatureを触ったことがなかったので今回他記事を参考に実装していきます。

〇Renderer Featurerとは?

URP Renderer FeaturerはURPで提供されている機能で、レンダリング時の任意のタイミングに処理(パス)を定義して挟むことができる機能です。

もともとURP自体がScriptable(C#でスクリプトが可能な)レンダーパイプライン(描画処理)ですので当然Renderer FeaturerはC#で記述することになります。

〇環境

・Unity2021.3.5f1

・UniversalRP 12.1.7

〇Renderer Featurerの作成と基本

URP RendererFeatureを作成するにはAssetsウィンドウ上で右クリック、Create→Rendering→URP Renderer Featureを選択します。

Renderer Featurerを作成するとデフォルトで次のような構成をしています。

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

public class CustomRenderPassFeature : ScriptableRendererFeature
{
    class CustomRenderPass : ScriptableRenderPass
    {
 public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
        {
        }
        public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
        {
        }
        public override void OnCameraCleanup(CommandBuffer cmd)
        {
        }
    }

    public override void Create()
    {
        m_ScriptablePass = new CustomRenderPass();
        m_ScriptablePass.renderPassEvent = RenderPassEvent.AfterRenderingOpaques;
    }
    public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    {
        renderer.EnqueuePass(m_ScriptablePass);
    }
}

ScriptableRenderPassを継承するCustomRenderPassが描画パスにあたります。 

ScriptableRendererFeatureを継承するクラスCustomRenderPassFeatureがURPで認識されパスを生成するための枠組みのようなものになります。

ScriptableRendererFeatureが作成されるとURPAssetsのRendererにAdd Renderer Featureから作成したものが指定可能になります。今回の場合はPostProcessing Testと名付けています。

追加することでScriptableRendererFeatureの設定が完了します。

〇パスの構成

ScriptableRenderPassを継承するパスのクラスではOnCameraSetup()Execute()の二つのメソッドが定義されています。

    class CustomRenderPass : ScriptableRenderPass
    {
 public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
        {
        }
        public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
        {
        }
        public override void OnCameraCleanup(CommandBuffer cmd)
        {
        }
    }

重要なのはExexute()でこちらが具体的な描画パスを記述します。

では実際に処理を追っていきます。

まずはコマンドバッファを取得します。コマンドバッファとはURPのレンダリングに使用するグラフィックコマンドを保持するリストです。

context.ExecuteCommandBuffer(commandBuffer);

の一行で初期化を行っています。

途中で処理を行いScriptableRenderContext.DrawRenderers()で描画の実行を行います。

docs.unity3d.com

ScriptableRenderContext.DrawRenderers()は最低3つの引数を持っており、第一引数にカリング(どのオブジェクトを描画するのか?)、第二引数に描画設定、第三引数にフィルタリングを渡します。

        public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
        {
          context.ExecuteCommandBuffer(commandBuffer);
                //初期化
                commandBuffer.Clear();
                
                  //カメラにレンダリングされているデータ
                var camera = renderingData.cameraData.camera;
                var sortingSettings = new SortingSettings(camera);
                var drawingSettings = new DrawingSettings(new ShaderTagId("SamplePass"), sortingSettings);
                var filteringSettings = new FilteringSettings(RenderQueueRange.opaque);
                
                //描画の実行
                context.DrawRenderers(renderingData.cullResults, ref drawingSettings, ref filteringSettings);
        }

今回は初めてCustomREndererFeatureを使用していきました。

長くなってしまったので続きは次回勉強していきます。

〇参考

docs.unity3d.com

qiita.com