Unity URP自定义后处理系统

目录

 

前言:

一、前期了解

ScriptableRendererFeature

ScriptableRenderPass

VolumeComponent

二、创建系统

准备:

实操:

1.CustomPostProcessRenderFeature

2.CustomPostProcessVolume

3.CustomPostProcessRenderPass

三、完整代码 

CustomPostProcessRenderFeature

CustomPostProcessVolume

CustomPostProcessRenderPass

四、案例

五、一些问题 


前言:

在游戏制作过程中,后处理效果的增加能够给我们的画面带来许多眼前一亮的效果,画面的美化。而在URP中不同于BuildIn管线,URP需要自定义RenderFeature来实现一个个后处理,但是能不能像URP内置的后处理一样只有一个RenderPass呢?如下图:

6e85840624e74391b4940c65dc9c8170.png

答案当然是肯定的!

这是我学习参考的文章:Unity URP14.0 自定义后处理系统 - 知乎

上面的文章是基础,当然里面的介绍对于没有接触过RenderFeature这些有点不友好(当初我学习的时候也是一脸没看懂,笑~【有一个网页的文章找不到了,那篇其实比较完全,但是没关系,下面我会介绍我使用系统所遇到的所有问题和解决办法】)。

小破站的视频是我依据上面的文章所写的工具脚本(是早期版本啦,下面的文章是更全面,考虑情况更多的系统,如果是学习的话可以看看小破站链接里的代码,如果是学习系统如何创建的,请跳过这些)。

一、前期了解

RenderFeature代码的创立可以用Unity自带的创建方法,如下图:

1c8a2a5ec5f34689864751f7026cd7eb.gif

f65bca5c98c44b3eaafb84071043157d.png

打开之后我们可以看到CustomRenderPassFeature继承ScriptableRendererFeature,其中又定义了一个继承ScriptableRenderPassCustomRenderPass类。

ScriptableRendererFeature

330f0f9a4b0d43919a8430e3c0d580c6.png

ScriptableRendererFeature能够将我们定义的ScriptableRenderPass插入到CameraRender序列里,让Camera进行渲染。

ScriptableRenderPass

f736521fd1ac4999aad9cef3607f385e.png

ScriptableRenderPass定义了我们该如何渲染此通道(也就是我们核心处理后处理逻辑的地方)。

相关的我就不多说了,里面的函数方法周期我也不再介绍,大家可以去看官方文档。

VolumeComponent

2ca8b57543774b46ba92b38ab5e60e5b.png

相信使用URP内置的后处理效果时,都会使用Volume组件

6f5833e46f434b31a7b821853fbce5ad.png

这是为了方便我们进行效果调节的组件,当然Volume也可以有其它的效果,我们接下来的系统也会借助这个组件功能来调节我们的后效,具体的Volume可以参考官方文档,我就不再介绍了。

二、创建系统

准备:

首先我们先思考一下我们的系统需要实现什么功能。

1.在RenderSetting添加自定义的后效RenderFeature,此Feature只能添加一次

2.RenderFeature插入我们的自定义后效RenderPass,这个RenderPass会遍历我们所有的自定义的后效,根据后效的启用与否,来决定是否在render序列里进行添加。

3.自定义Volume组件,可以在Volume下调节效果。

4.优化:每个效果尽力只调用一次渲染命令。

实操:

首先创建3个脚本,分别是CustomPostProcessRenderFeatureCustomPostProcessRenderPassCustomPostProcessVolume

66dbbd5e34bb4fe89bc6a4751580c70e.png

根据命名就知道它们各自的分工是什么。

1.CustomPostProcessRenderFeature

using UnityEngine;
using UnityEngine.Rendering.Universal;

[DisallowMultipleRendererFeature]
public class CustomPostProcessRenderFeature : ScriptableRendererFeature
{
    CustomPostProcessRenderPass m_renderPass;
    [SerializeField] private RenderPassEvent m_passRenderEvent = RenderPassEvent.BeforeRenderingPostProcessing;
    public override void Create()
    {
        m_renderPass = new CustomPostProcessRenderPass();
        m_renderPass.renderPassEvent = m_passRenderEvent;
    }

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

89e7d2807ae9425b93529222c8f61e14.png

可以看到CustomPostProcessRenderFeature继承ScriptableRendererFeature

在类的上方有一个特性[DisallowMultipleRendererFeature],旨在CustomPostProcessRenderFeature只能添加一次。

Create方法里我们初始化RenderPass,并且设置了RenderPass插入的渲染事件7404dcdee9bd4a0e83556e4a66647a5a.png

而在AddRenderPasses方法里我们将RenderPass进行正式的添加到Camera的render序列里。

8c3d8f710a434ef687dfcb5c49b87363.png

2.CustomPostProcessVolume

using System;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
public abstract class CustomPostProcessVolume : VolumeComponent, IPostProcessComponent
{
    private Material material;
    public abstract string shaderPath { get; }
    public Material m_material
    {
       

猜你喜欢

转载自blog.csdn.net/m0_68267247/article/details/143731575