URP 2022.3 custom render pass

这里需要注意,有两个部分要做,一步是写脚本和shader,一步是在editor里进行绑定
这里有个概念上需要注意的,他这个pass啊,实际依赖问题都需要你自己在execute处理的,比如你要画N次东西,就要在execute里自己把逻辑梳理清楚,调用Blit进行绘制,然后读取,然后绘制,下面代码会有体现
这是 官方用法
先说第二步,我感觉第二步更加关键,我这里虽然名字是Blur,但是效果不是,我进行了化简,名字是因为我直接从上面的链接copy的代码
在这里插入图片描述
最下面这个add renderer feature按钮,当你完整的写完一个render feature组件后,这里是能识别到的,你点击他 下拉列表就有你刚写好的feature,所以关键就是找到你正在使用的renderer,添加你写好的render feature即可

下面说代码怎么写的
流程上,这里已知需要一个render feature,然后他会将PASS添加到渲染流程的执行时间点上
所以,我们需要的物件就是
在这里插入图片描述

这个feature的代码可以说是很简单
create就创建pass,指定inject point
dispose就是清理数据
add就是把pass对象加入渲染流程,render就不用你管了,会在对应的时间点执行pass的execute的

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

public class BlurRendererFeature : ScriptableRendererFeature
{
    
    
    [SerializeField] private Shader shader;
    private Material material;
    private BlurRenderPass blurRenderPass;

    public override void Create()
    {
    
    
        if (shader == null)
        {
    
    
            return;
        }
        material = new Material(shader);
        blurRenderPass = new BlurRenderPass(material);

        blurRenderPass.renderPassEvent = RenderPassEvent.AfterRenderingSkybox;
    }

    public override void AddRenderPasses(ScriptableRenderer renderer,
        ref RenderingData renderingData)
    {
    
    
        if (renderingData.cameraData.cameraType == CameraType.Game)
        {
    
    
            renderer.EnqueuePass(blurRenderPass);
        }
    }

    protected override void Dispose(bool disposing)
    {
    
    
        blurRenderPass.Dispose();
#if UNITY_EDITOR
        if (EditorApplication.isPlaying)
        {
    
    
            Destroy(material);
        }
        else
        {
    
    
            DestroyImmediate(material);
        }
#else
                Destroy(material);
#endif
    }
}

下面就是pass了,
需要的成员变量,材质,渲染纹理描述,渲染对象的句柄(这里应该就是对应OpenGL的FBO的ID
唯一一个关联就是这个函数 RenderingUtils.ReAllocateIfNeeded,应该就是函数内部逻辑判断如果需要的话,就创建一个texture然后返回ID
构造函数就给材质赋值,初始化一个FBO纹理的描述
这个configure函数类似窗口resize啥的需要重绘反正就要重新设置一下size类似这种
然后就是Blit函数,前面几个好理解,最后一个参数是你的material的shader里的pass的index

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

public class BlurRenderPass : ScriptableRenderPass
{
    
    
   
    private Material material;

    private RenderTextureDescriptor blurTextureDescriptor;
    private RTHandle blurTextureHandle;

    public BlurRenderPass(Material material)
    {
    
    
        this.material = material;

        blurTextureDescriptor = new RenderTextureDescriptor(Screen.width,
            Screen.height, RenderTextureFormat.Default, 0);
    }

    public override void Configure(CommandBuffer cmd,
        RenderTextureDescriptor cameraTextureDescriptor)
    {
    
    
        // Set the blur texture size to be the same as the camera target size.
        blurTextureDescriptor.width = cameraTextureDescriptor.width;
        blurTextureDescriptor.height = cameraTextureDescriptor.height;

        // Check if the descriptor has changed, and reallocate the RTHandle if necessary
        RenderingUtils.ReAllocateIfNeeded(ref blurTextureHandle, blurTextureDescriptor);
    }



    public override void Execute(ScriptableRenderContext context,
        ref RenderingData renderingData)
    {
    
    
        //Get a CommandBuffer from pool.
        CommandBuffer cmd = CommandBufferPool.Get();

        RTHandle cameraTargetHandle =
            renderingData.cameraData.renderer.cameraColorTargetHandle;

        

        // Blit from the camera target to the temporary render texture,
        // using the first shader pass.
        Blit(cmd, cameraTargetHandle, blurTextureHandle, material, 0);
        // Blit from the temporary render texture to the camera target,
        // using the second shader pass.
        Blit(cmd, blurTextureHandle, cameraTargetHandle, material, 1);

        //Execute the command buffer and release it back to the pool.
        context.ExecuteCommandBuffer(cmd);
        CommandBufferPool.Release(cmd);
    }

    public void Dispose()
    {
    
    
#if UNITY_EDITOR
        if (EditorApplication.isPlaying)
        {
    
    
            Object.Destroy(material);
        }
        else
        {
    
    
            Object.DestroyImmediate(material);
        }
#else
                Object.Destroy(material);
#endif

        if (blurTextureHandle != null) blurTextureHandle.Release();
    }
}

这是HLSL风格,#pragma指定函数入口,提示说vert函数在blit.hlsl里,不需要写
这里就有俩PASS,Blit的最后一个函数就是指定此次渲染你要使用第几个,我这里第一次叠加蓝色,第二次叠加红色,最终画面呈现紫色

Shader "CustomRenderTexture/Blur"
{
    
    
    HLSLINCLUDE
    
        #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
        // The Blit.hlsl file provides the vertex shader (Vert),
        // the input structure (Attributes), and the output structure (Varyings)
        #include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"

        
    
        float4 BlurVertical (Varyings input) : SV_Target
        {
    
    
            return SAMPLE_TEXTURE2D(_BlitTexture, sampler_LinearClamp, input.texcoord) + float4(0.0, 0.0, 1.0, 0.2);
        }

        float4 BlurHorizontal (Varyings input) : SV_Target
        {
    
    
            return SAMPLE_TEXTURE2D(_BlitTexture, sampler_LinearClamp, input.texcoord) + float4(1.0, 0.0, 0.0, 0.2);
        }
    
    ENDHLSL
    
    SubShader
    {
    
    
        Tags {
    
     "RenderType"="Opaque" "RenderPipeline" = "UniversalPipeline"}
        LOD 100
        ZWrite Off Cull Off
        Pass
        {
    
    
            Name "BlurPassVertical"

            HLSLPROGRAM
            
            #pragma vertex Vert
            #pragma fragment BlurVertical
            
            ENDHLSL
        }
        
        Pass
        {
    
    
            Name "BlurPassHorizontal"

            HLSLPROGRAM
            
            #pragma vertex Vert
            #pragma fragment BlurHorizontal
            
            ENDHLSL
        }
    }
}

在这里插入图片描述
在这里插入图片描述