うにてぃブログ

主にUnityとC#に関する記事を書いていきます

【Unity】URP14で動作する RendererFeature の PostProcessing 処理

動作環境 Unity2022.2.0b16 URP 14.0.3

Unity2021で動作していた RendererFeature の PostProcessing 処理をそのまま移植したところ動作しなかったので動作するように修正しました

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

[Serializable]
public class SampleRendererFeature : ScriptableRendererFeature
{
    [SerializeField]
    private Shader _shader;
    private SampleRendererPass _pass;
    
    public override void Create()
    {
        _pass = new SampleRendererPass(_shader);
    }
    public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    {
        renderer.EnqueuePass(_pass);
    }

    protected override void Dispose(bool disposing)
    {
        _pass.Dispose();
        base.Dispose(disposing);
    }
}

public class SampleRendererPass : ScriptableRenderPass
{
    private const string _name = nameof(SampleRendererPass);
    private Material _material;
    private RTHandle _tempHandle;
    
    public SampleRendererPass(Shader shader)
    {
        if (shader == null)
            return;
        
        renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing;
        _material = CoreUtils.CreateEngineMaterial(shader);
    }
    
    public void Dispose()
    {
        CoreUtils.Destroy(_material);
        _tempHandle.Release();
    }
    
    public override void Execute(ScriptableRenderContext context, ref RenderingData data)
    {
        if (_material == null
            || !data.cameraData.postProcessEnabled
            || data.cameraData.cameraType == CameraType.SceneView
            )
        {
            return;
        }
        
        var targetHandle = data.cameraData.renderer.cameraColorTargetHandle;
        var commandBuffer = CommandBufferPool.Get(_name);
        commandBuffer.Clear();
        
        // depthBufferBits = 0 じゃないと真っ黒になってしまう
        var tempDescriptor = data.cameraData.cameraTargetDescriptor;
        tempDescriptor.depthBufferBits = 0;
        RenderingUtils.ReAllocateIfNeeded(ref _tempHandle, tempDescriptor, name: "_TempHandle");
        // 仮のバッファにコピーする
        Blit(commandBuffer, targetHandle, _tempHandle);
        // 仮のバッファを加工して元に戻す        
        Blit(commandBuffer, _tempHandle, targetHandle, _material, 0);
        // 以下の処理でもよい
        // Blitter.BlitCameraTexture(commandBuffer, _tempHandle, targetHandle, _material, 0);
        
        context.ExecuteCommandBuffer(commandBuffer);
        CommandBufferPool.Release(commandBuffer);
    }
}

ただ Shader 側の Blit したテクスチャが _SourceTex だったのが名前が変わって _BlitTexture になっていました

それ以外ににも sampler_BlitTexture の定義がなかったので sampler_LinearClamp を利用しています

他には #pragma vertex FullscreenVert の定義が削除されたので #pragma vertex Vert を利用しています

Shader "Hidden/SampleImageEffectShader"
{
    SubShader
    {
        Cull Off ZWrite Off ZTest Always

        Pass
        {

            HLSLPROGRAM
            #pragma vertex Vert
            #pragma fragment frag
            
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/Shaders/PostProcessing/Common.hlsl"

            half4 frag(Varyings i) : SV_Target
            {
                half4 col = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_PointClamp, i.texcoord);
                col.rgb = 1 - col.rgb;
                return col;
            }
            
            ENDHLSL
        }
    }
}