using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; /// /// Grab Pass 特性:将当前颜色缓冲绑定为 _CameraColorAttachmentA 供热扭曲等效果使用 /// public class GrabPassFeature : ScriptableRendererFeature { [System.Serializable] public class Settings { public RenderPassEvent renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing; public string shaderTagName = "Grab"; public LayerMask layerMask = -1; [Header("性能设置")] [Tooltip("采样分辨率缩放(1.0 = 全分辨率,0.5 = 半分辨率)")] [Range(0.25f, 1f)] public float resolutionScale = 1f; } public Settings settings = new Settings(); private GrabPass grabPass; public override void Create() { grabPass = new GrabPass(settings); } public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) { renderer.EnqueuePass(grabPass); } protected override void Dispose(bool disposing) { grabPass?.Dispose(); } class GrabPass : ScriptableRenderPass { private readonly ShaderTagId shaderTagId; private FilteringSettings filteringSettings; private readonly Settings settings; private RTHandle tempColorTarget; public GrabPass(Settings settings) { this.settings = settings; renderPassEvent = settings.renderPassEvent; shaderTagId = new ShaderTagId(settings.shaderTagName); filteringSettings = new FilteringSettings(RenderQueueRange.transparent, settings.layerMask); ConfigureInput(ScriptableRenderPassInput.Color); } public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData) { var descriptor = renderingData.cameraData.cameraTargetDescriptor; descriptor.width = Mathf.Max(1, Mathf.CeilToInt(descriptor.width * settings.resolutionScale)); descriptor.height = Mathf.Max(1, Mathf.CeilToInt(descriptor.height * settings.resolutionScale)); descriptor.depthBufferBits = 0; descriptor.msaaSamples = 1; RenderingUtils.ReAllocateIfNeeded(ref tempColorTarget, descriptor, FilterMode.Bilinear, TextureWrapMode.Clamp, name: "_GrabPassTemp"); } public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) { if (tempColorTarget == null) return; var cmd = CommandBufferPool.Get("Grab Pass"); var sourceColorTarget = renderingData.cameraData.renderer.cameraColorTargetHandle; cmd.Blit(sourceColorTarget.nameID, tempColorTarget.nameID); cmd.SetGlobalTexture("_CameraColorAttachmentA", tempColorTarget.nameID); cmd.SetRenderTarget(sourceColorTarget, RenderBufferLoadAction.Load, RenderBufferStoreAction.Store); context.ExecuteCommandBuffer(cmd); cmd.Clear(); var drawingSettings = CreateDrawingSettings(shaderTagId, ref renderingData, SortingCriteria.CommonTransparent); context.DrawRenderers(renderingData.cullResults, ref drawingSettings, ref filteringSettings); CommandBufferPool.Release(cmd); } public void Dispose() { tempColorTarget?.Release(); } } }