Unity URP管线如何实现屏幕后处理
URP管线可扩展的自己的 RendererFeature,这里写了一个屏幕后处理的demo,首先shader如下:
1 Shader "MyURP/Kerry/PostProcess/URPFeature_PostProcessDemo" 2 { 3 Properties 4 { 5 _MainTex("Main Texture", 2D) = "white" {} 6 _Color("test", Color) = (1,1,1,1) 7 } 8 9 SubShader 10 { 11 Tags 12 { 13 "RenderType" = "Opaque" 14 "RenderPipeline" = "UniversalPipeline" 15 } 16 17 Pass 18 { 19 Cull Off 20 ZWrite Off 21 ZTest Always 22 23 HLSLPROGRAM 24 #pragma vertex vert 25 #pragma fragment frag 26 #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" 27 28 TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex); 29 half4 _Color; 30 31 struct appdata 32 { 33 float4 vertex : POSITION; 34 float2 uv : TEXCOORD0; 35 }; 36 37 struct v2f 38 { 39 float4 pos : SV_POSITION; 40 float2 uv : TEXCOORD0; 41 }; 42 43 v2f vert(appdata v) 44 { 45 v2f o; 46 o.pos = mul(UNITY_MATRIX_MVP, v.vertex); 47 o.uv = v.uv; 48 return o; 49 } 50 51 half4 frag(v2f i) : SV_TARGET 52 { 53 return SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv) * _Color; 54 } 55 56 ENDHLSL 57 } 58 } 59 60 FallBack "Hidden/Universal Render Pipeline/FallbackError" 61 }
可以看到,这里就是输入一个颜色并叠加到屏幕颜色上。
C# RenderFeature代码如下:
1 using System; 2 using UnityEngine; 3 using UnityEngine.Rendering; 4 using UnityEngine.Rendering.Universal; 5 6 public class URPFeature_PostProcessDemo : ScriptableRendererFeature 7 { 8 class URPPass_PostProcessDemo : ScriptableRenderPass 9 { 10 Settings m_Settings; 11 RenderTargetIdentifier m_source; 12 RenderTargetIdentifier m_dest; 13 14 public URPPass_PostProcessDemo(Settings settings) 15 { 16 m_Settings = settings; 17 } 18 19 public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData) 20 { 21 m_source = renderingData.cameraData.renderer.cameraColorTarget; 22 23 int tempRTName = Shader.PropertyToID("URPFeature_PostProcessDemo_TempRT"); 24 cmd.GetTemporaryRT(tempRTName, renderingData.cameraData.cameraTargetDescriptor); 25 m_dest = new RenderTargetIdentifier(tempRTName); 26 } 27 28 public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) 29 { 30 m_Settings.m_mat.SetColor("_Color", m_Settings.m_Color); 31 32 CommandBuffer cmd = CommandBufferPool.Get("URPFeature_PostProcessDemo_cmd"); 33 Blit(cmd, m_source, m_dest, m_Settings.m_mat, 0); 34 Blit(cmd, m_dest, m_source); 35 context.ExecuteCommandBuffer(cmd); 36 CommandBufferPool.Release(cmd); 37 } 38 } 39 40 [Serializable] 41 public class Settings 42 { 43 public Material m_mat; 44 public Color m_Color = Color.white; 45 } 46 47 [SerializeField] 48 Settings m_Settings; 49 URPPass_PostProcessDemo m_pass; 50 51 52 public override void Create() 53 { 54 m_pass = new URPPass_PostProcessDemo(m_Settings); 55 } 56 57 public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) 58 { 59 if (m_Settings.m_mat) 60 { 61 renderer.EnqueuePass(m_pass); 62 } 63 } 64 65 66 }
最后,我们把这个feature加到URP管线中,如下:
调整颜色值,发现屏幕颜色发生了改变: