URP—自定义后处理流程
前记:默认的build-in管线的后处理挺简单,但是换了urp还想上后处理,使用这几天进行了学习---------------------mx
屏幕后处理:通常指在渲染完整个场景得到屏幕图像之后再对这个图像进行一系列操作,实现各种屏幕特效。
在build-in的管线中,后处理的基本流程是:
URP后处理前期准备
在包管理器中导入Universal RP,右键创建Assets/Create/Rendering/Universal Render Pipeline/Pipeline Asset
这里可以加入自定义的后处理
然后在设置中修改当前可编写脚本的渲染管线设置,改为刚才创建的pipeline
然后右键创建Assets/Create/Rendering/Universal Render Pipeline/RendererFeature,会出现一个脚本里面有两个类分别继承了ScriptableRendererFeature,ScriptableRenderPass
我们先来了解一下继承了ScriptableRendererFeature的类吧
首先public的变量都会在资产面板中显示
2.需要重写的Create函数是在RendererFeature被创建时调用,这个方法里通常实现的功能是实例化那个继承了ScriptableRenderPass的类
3.需要重写的AddRenderPasses函数是渲染的每一帧都会调用,通常做的就是把当前已经渲染出来的RenderTexture传入到继承了ScriptableRenderPass的类(对自定义的Pass进行初始化),然后在Renderer插入那个继承了ScriptableRenderPass的类
4.其他:如Dispose函数是在一帧执行完之后调用
然后看一下继承了ScriptableRenderPass的类
实战:做一个可以改变屏幕亮度、饱和度、对比度的后处理
后处理脚本
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
public class Test : ScriptableRendererFeature
{
public class RendererPassTest : ScriptableRenderPass
{
Material m_Mat = new Material(Shader.Find("Custom/PostEffect"));
//RT的Filter
public FilterMode filterMode { get; set; }
//当前阶段渲染的颜色RT
RenderTargetIdentifier m_Source;
//辅助RT
RenderTargetHandle m_TemporaryColorTexture;
//Profiling上显示
ProfilingSampler m_ProfilingSampler = new ProfilingSampler("URPTest");
public RendererPassTest()
{
//在哪个阶段插入渲染
renderPassEvent = RenderPassEvent.AfterRenderingOpaques;
//初始化辅助RT名字
m_TemporaryColorTexture.Init("URPBaseTest");
}
public void Setup(RenderTargetIdentifier source, float brightness, float saturate, float contranst)
{
m_Source = source;
//m_Color = color;
m_Mat.SetFloat("_brightness", brightness);
m_Mat.SetFloat("_saturate", saturate);
m_Mat.SetFloat("_contranst", contranst);
}
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
CommandBuffer cmd = CommandBufferPool.Get();
//using的做法就是可以在FrameDebug上看到里面的所有渲染
using (new ProfilingScope(cmd, m_ProfilingSampler))
{
//创建一张RT
RenderTextureDescriptor opaqueDesc = renderingData.cameraData.cameraTargetDescriptor;
opaqueDesc.depthBufferBits = 0;
cmd.GetTemporaryRT(m_TemporaryColorTexture.id, opaqueDesc, filterMode);
//将当前帧的颜色RT用自己的着色器渲处理然后输出到创建的贴图上
Blit(cmd, m_Source, m_TemporaryColorTexture.Identifier(), m_Mat);
//将处理后的RT重新渲染到当前帧的颜色RT上
Blit(cmd, m_TemporaryColorTexture.Identifier(), m_Source);
}
//执行
context.ExecuteCommandBuffer(cmd);
//回收
CommandBufferPool.Release(cmd);
}
public override void FrameCleanup(CommandBuffer cmd)
{
base.FrameCleanup(cmd);
//销毁创建的RT
cmd.ReleaseTemporaryRT(m_TemporaryColorTexture.id);
}
}
//会显示在资产面板上
public Color m_Color = Color.red;
public float contranst;
public float saturate;
public float brightness;
RendererPassTest m_Pass;
//feature被创建时调用
public override void Create()
{
m_Pass = new RendererPassTest();
}
//每一帧都会被调用
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
//将当前渲染的颜色RT传到Pass中
m_Pass.Setup(renderer.cameraColorTarget, brightness, saturate,contranst);
//将这个pass添加到渲染队列
renderer.EnqueuePass(m_Pass);
}
//一帧渲染完最后调用
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
}
}
shader
Shader "Custom/PostEffect"
{
Properties
{
[HideInInspector] _MainTex ("Albedo (RGB)", 2D) = "white" {}
_brightness ("Brightness", Range(0,1)) = 0.5
_saturate ("Saturate", Range(0,1)) = 0.0
_contranst ("Constrast", Range(-1,2)) = 0.0
}
SubShader
{
Tags
{
"RenderPipeline"="UniversalRenderPipeline"
}
pass
{
Cull Off
ZWrite Off
ZTest Always
HLSLPROGRAM
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
CBUFFER_START(UnityPerMaterial)
float _brightness;
float _saturate;
float _contranst;
CBUFFER_END
TEXTURE2D(_MainTex);
SAMPLER(sampler_MainTex);
struct a2v{
float4 positionOS:POSITION;
float2 texcoord:TEXCOORD;
};
struct v2f
{
float4 positionCS:SV_POSITION;
float2 texcoord:TEXCOORD;
};
#pragma vertex Vert
#pragma fragment Frag
v2f Vert(a2v i)
{
v2f o;
o.positionCS =TransformObjectToHClip(i.positionOS.xyz);
o.texcoord = i.texcoord;
return o;
}
float4 Frag(v2f i) :SV_TARGET
{
float4 tex = SAMPLE_TEXTURE2D(_MainTex,sampler_MainTex,i.texcoord);
float gray = 0.21*tex.x + 0.72 * tex.y + 0.072*tex.z;
tex.xyz *= _brightness;
tex.xyz = lerp (float3(gray,gray,gray), tex.xyz, _saturate);
tex.xyz = lerp (float3(0.5,0.5,0.5), tex.xyz, _contranst);
return tex;
}
ENDHLSL
}
}
}
---------------------博主:mx