【從UnityURP開始探索遊戲渲染】專欄-直達
FullScreenPassRendererFeature是Unity URP渲染管線中用於實現全屏後處理效果的核心組件,它允許開發者在渲染流程的特定階段插入自定義的全屏着色器效果。
功能與作用
- 核心功能:通過ScriptableRenderPass在URP管線中注入全屏四邊形繪製命令,應用自定義Shader實現屏幕空間特效(如模糊、色調調整等)
-
典型應用場景:
- 屏幕後處理(如Bloom、景深模擬)
- 全局濾鏡效果(黑白化、夜視模式)
- 特殊視覺特效(掃描線、像素化)
發展歷史
- URP初期:需手動編寫完整的ScriptableRendererFeature和ScriptableRenderPass類實現全屏效果
- URP 7.0+ :引入預置的FullScreenPassRendererFeature簡化開發流程
- URP 17.0:重構API至RenderGraph系統,優化資源管理機制
原理
FullScreenPassRendererFeature是Unity URP中用於實現全屏後處理效果的核心組件,其底層原理基於URP的可編程渲染管線架構。
核心原理
- 繼承關係:繼承自
ScriptableRendererFeature基類,通過Create()方法初始化自定義的ScriptableRenderPass子類實例 - 執行流程:在URP渲染管線的特定階段(如不透明物體渲染後)插入全屏繪製命令,通過
CommandBuffer調用Blit或DrawProcedural實現 - 資源管理:使用
RTHandle系統動態管理渲染目標,自動處理不同分辨率下的資源分配與釋放
關鍵代碼示例
以下實現一個基礎的全屏泛光效果:
-
BloomFeature.cs
using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; [System.Serializable] public class BloomSettings { public float intensity = 1.0f; public Color tint = Color.white; } public class BloomFeature : ScriptableRendererFeature { public BloomSettings settings = new BloomSettings(); private BloomPass m_Pass; public override void Create() { m_Pass = new BloomPass(settings); m_Pass.renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing; } public override void AddRenderPasses( ScriptableRenderer renderer, ref RenderingData renderingData) { renderer.EnqueuePass(m_Pass); } } class BloomPass : ScriptableRenderPass { private Material m_Material; private BloomSettings m_Settings; private RTHandle m_TempTexture; public BloomPass(BloomSettings settings) { m_Settings = settings; m_Material = CoreUtils.CreateEngineMaterial("Hidden/Blur"); } public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) { m_TempTexture = RTHandles.Alloc( Vector2.one * 0.5f, colorFormat: cameraTextureDescriptor.colorFormat); } public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) { var cmd = CommandBufferPool.Get("BloomPass"); Blit(cmd, renderingData.cameraData.renderer.cameraColorTargetHandle, m_TempTexture, m_Material, 0); Blit(cmd, m_TempTexture, renderingData.cameraData.renderer.cameraColorTargetHandle); context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); } public override void FrameCleanup(CommandBuffer cmd) { m_TempTexture.Release(); } }
技術細節
- 材質控制:通過Shader的
LightMode標籤匹配(如UniversalForward)確定渲染路徑 - 時序控制:
RenderPassEvent枚舉精確控制執行時機(如AfterRenderingOpaques) - 多Pass協作:支持通過多個
ScriptableRenderPass實現效果疊加,如先提取亮部再模糊
性能優化
- 臨時紋理複用:通過
RTHandle的縮放參數實現動態分辨率渲染 - 命令緩衝池:使用
CommandBufferPool減少GC開銷 - 材質實例化:避免每幀創建新材質
該機制相比傳統OnRenderImage方案,在URP中能更好地集成到SRP批處理系統中,且支持XR多通道渲染等高級特性
實現流程示例
以下為完整實現黑白濾鏡效果的URP示例:
-
GrayFeature.cs
using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; public class GrayRenderFeature : ScriptableRendererFeature { public RenderPassEvent renderEvent = RenderPassEvent.AfterRendering; public Shader shader; private Material grayMaterial; private GrayPass grayPass; public override void Create() { grayMaterial = CoreUtils.CreateEngineMaterial(shader); grayPass = new GrayPass(grayMaterial, renderEvent); } public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) { grayPass.SetTarget(renderer.cameraColorTargetHandle); renderer.EnqueuePass(grayPass); } } public class GrayPass : ScriptableRenderPass { private Material material; private RTHandle source; public GrayPass(Material material, RenderPassEvent passEvent) { this.material = material; this.renderPassEvent = passEvent; } public void SetTarget(RTHandle colorHandle) { source = colorHandle; } public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) { CommandBuffer cmd = CommandBufferPool.Get("GrayEffect"); Blitter.BlitCameraTexture(cmd, source, source, material, 0); context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); } } -
GrayEffect.shader
Shader "Custom/GrayEffect" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} } SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; sampler2D _MainTex; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } fixed4 frag (v2f i) : SV_Target { fixed4 col = tex2D(_MainTex, i.uv); float gray = dot(col.rgb, float3(0.299, 0.587, 0.114)); return fixed4(gray, gray, gray, col.a); } ENDCG } } }
參數説明與用例
| 參數 | 類型 | 説明 | 典型值 |
|---|---|---|---|
| renderEvent | RenderPassEvent | 執行時機 | AfterRenderingOpaques |
| shader | Shader | 效果着色器 | 自定義全屏Shader |
| intensity | float | 效果強度 | 0.0-1.0 |
實際配置步驟:
- 創建URP Renderer Asset(若不存在)
- 通過Inspector添加FullScreenPassRendererFeature
- 指定Material並使用ShaderGraph創建效果
- 調整RenderPassEvent控制執行順序
性能優化建議
- 使用RTHandle管理渲染目標避免內存浪費
- 複雜效果建議結合Volume系統實現參數動態調整
- 移動端需注意帶寬佔用,推薦使用Half Resolution處理
【從UnityURP開始探索遊戲渲染】專欄-直達
(歡迎點贊留言探討,更多人加入進來能更加完善這個探索的過程,🙏)