Unity URP下后处理如何实现

关于URP中后处理的博客一直没有找到写的比较直白的,现在自己搞清楚了,决定用通俗的语言记录一下,其实流程极其简单

要实现功能,离不开下图这三个文件
在这里插入图片描述

Volume文件用于在面板中设置参数
ReaderFeature包含核心渲染逻辑
Shader文件用于具体实现画面效果(自由发挥时刻)

下面是一个实现获取深度纹理的示例,用于理解URP下的后处理流程

1.Volume

此文件主要用于在volume组件中添加对效果的控制

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

public class CustomVolume : VolumeComponent, IPostProcessComponent
{ 
    [Tooltip("颜色")]
    public ColorParameter color = new ColorParameter(Color.white);


    public bool IsActive()
    {
        throw new System.NotImplementedException();
    }

    public bool IsTileCompatible()
    {
        throw new System.NotImplementedException();
    }

}


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

2.RenderFeature

此文件为后处理渲染配置 ,可以说是核心文件。
首先,需要一个存储渲染配置信息的类,没什么具体的要求,很多博主喜欢放在RenderFeature类内,最好还是单独建一个文件,这样之后做其他效果也可以通用。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering.Universal;

/// <summary>
/// 渲染特性配置信息
/// </summary>
[System.Serializable]
public class RenderFeatureSettings
{
    //渲染发生的阶段,具体信息可以在枚举类RenderPassEvent中查看
    public RenderPassEvent renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing;
    //后处理用到的shader
    public Shader shader;

    public RenderFeatureSettings()
    {
    }
    public RenderFeatureSettings(RenderPassEvent renderPassEvent, string shaderStr)
    {
        this.renderPassEvent = renderPassEvent;
        this.shader = Shader.Find(shaderStr);
    }
}

重头戏,RenderFeature类,此类作用是实现渲染的逻辑,需要在管线配置文件中点击Add Renderer Feature添加,如图所示。在这里插入图片描述
类中还包含一个ScriptableRenderPass的子类。
代码里需要解释的地方已经写上注释,重点说几个方法:
1.CustomRenderPassFeature.Create 此方法在点击Add Renaderer Feature后触发
2.CustomRenderPass.Execute 渲染的执行,需要在此方法中写具体的渲染逻辑

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

public class CustomRenderPassFeature : ScriptableRendererFeature
{
    //配置信息
    public RenderFeatureSettings settings;
    //自定义的渲染pass
    CustomRenderPass m_ScriptablePass;

    private void OnEnable()
    {
        //配置信息创建最好放在OnEnable里,因为有调用Shader.Find,此方法不能在ScriptableObject子类的构造函数中调用
        settings = new RenderFeatureSettings(RenderPassEvent.BeforeRenderingPostProcessing, "Shader Graphs/Test");
    }

    public override void Create()
    {
        //将shader和管线的渲染阶段设置好
        m_ScriptablePass = new CustomRenderPass(settings.shader);
        m_ScriptablePass.renderPassEvent = settings.renderPassEvent;
    }

    public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    {
        m_ScriptablePass.Setup(m_ScriptablePass.renderPassEvent, renderer.cameraColorTarget, RenderTargetHandle.CameraTarget);
        //添加pass到渲染队列中
        renderer.EnqueuePass(m_ScriptablePass);
    }

    class CustomRenderPass : ScriptableRenderPass
    {
        CustomVolume customColor;
        Material mat;

        RenderTargetIdentifier m_Source;
        RenderTargetHandle m_Destination;

        //用以获取CommandBuffer的字符串,个人理解此字符串用于给获取到的CommandBuffer标记一个名字,方便在FrameDebbuger中查看
        const string k_RenderPostProcessingTag = "Render AdditionalPostProcessing Effects";

        private Shader shader;

        public CustomRenderPass(Shader shader)
        {
            this.shader = shader;
            //创建pass对应的材质,在后续CommandBuffer的渲染中会用到
            mat = CoreUtils.CreateEngineMaterial(shader);

        }

        public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
        {
            //获取Volume中的信息
            VolumeStack stack = VolumeManager.instance.stack;
            customColor = stack.GetComponent<CustomVolume>();
            //获取CommandBuffer
            var cmd = CommandBufferPool.Get(k_RenderPostProcessingTag);
            RenderTargetIdentifier source = renderingData.cameraData.renderer.cameraColorTarget;               
            RenderTextureDescriptor inRTDesc = renderingData.cameraData.cameraTargetDescriptor;
            inRTDesc.depthBufferBits = 0;
            int destination = Shader.PropertyToID("T1");
            //材质上设置深度图的颜色
            mat.SetColor("_Color",bloomColor.color.value);
            cmd.BeginSample("MyPostProccess");
            // 获取一张临时RT
            cmd.GetTemporaryRT(destination, inRTDesc.width, inRTDesc.height, 0, FilterMode.Bilinear, RenderTextureFormat.DefaultHDR); //申请一个临时图像,并设置相机rt的参数进去
            cmd.Blit(source, destination);
            cmd.Blit(destination, source, mat, 0);
            cmd.EndSample("MyPostProccess!");
            cmd.ReleaseTemporaryRT(destination);
            //执行CommandBuffer
            context.ExecuteCommandBuffer(cmd);
            CommandBufferPool.Release(cmd);
        }

        public void Setup(RenderPassEvent @event, RenderTargetIdentifier source, RenderTargetHandle destination)
        {
            renderPassEvent = @event;
            m_Source = source;
            m_Destination = destination;
        }
    }
}

3.Shader

可以使用ShaderGraph写,也可以不用,本文将使用ShaderGraph。
在这里插入图片描述
就是简单的获取深度图进行颜色的混合,效果如下。
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值