【URP】Unity[RendererFeatures]全屏后处理FullScreenPassRendererFeature
【从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开始探索游戏渲染】专栏-直达
(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,🙏)

FullScreenPassRendererFeature是Unity URP渲染管线中用于实现全屏后处理效果的核心组件,它允许开发者在渲染流程的特定阶段插入自定义的全屏着色器效果。 功能与作用 核
浙公网安备 33010602011771号