using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; namespace SLSFramework.Rendering.PostProcessing { public class ScriptablePostProcessorPass : ScriptableRenderPass { private List postProcessors; private List activePostProcessorIndex; private string profilerTag; private List profilingSamplers; private RTHandle sourceRT; private RTHandle targetRT; private RTHandle tempRTA; private RTHandle tempRTB; private const string tempRTAName = "_TemporaryRenderTextureA"; private const string tempRTBName = "_TemporaryRenderTextureB"; public ScriptablePostProcessorPass(string profilerTag, List postProcessors) { this.profilerTag = profilerTag; this.postProcessors = postProcessors; activePostProcessorIndex = new List(postProcessors.Count); profilingSamplers = postProcessors.Select(c => new ProfilingSampler(c.ToString())).ToList(); tempRTA = RTHandles.Alloc(tempRTAName, name: tempRTAName); tempRTB = RTHandles.Alloc(tempRTBName, name: tempRTBName); } public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) { var cmd = CommandBufferPool.Get(profilerTag); context.ExecuteCommandBuffer(cmd); cmd.Clear(); var descriptor = renderingData.cameraData.cameraTargetDescriptor; descriptor.msaaSamples = 1; descriptor.depthBufferBits = 0; targetRT = renderingData.cameraData.renderer.cameraColorTargetHandle; sourceRT = renderingData.cameraData.renderer.cameraColorTargetHandle; RenderingUtils.ReAllocateIfNeeded(ref tempRTA, descriptor, name: tempRTAName); if (activePostProcessorIndex.Count == 1) { int index = activePostProcessorIndex[0]; using (new ProfilingScope(cmd, profilingSamplers[index])) { postProcessors[index].Render(cmd, ref renderingData, sourceRT, tempRTA); } } else { RenderingUtils.ReAllocateIfNeeded(ref tempRTB, descriptor, name: tempRTBName); Blitter.BlitCameraTexture(cmd, sourceRT, tempRTA); foreach (int index in activePostProcessorIndex) { var postProcessor = postProcessors[index]; using (new ProfilingScope(cmd, profilingSamplers[index])) { postProcessor.Render(cmd, ref renderingData, tempRTA, tempRTB); } CoreUtils.Swap(ref tempRTA, ref tempRTB); } } Blitter.BlitCameraTexture(cmd, tempRTA, targetRT); context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); } public void Dispose() { if (tempRTA != null) RTHandles.Release(tempRTA); if (tempRTB != null) RTHandles.Release(tempRTB); } public bool Setup() { activePostProcessorIndex.Clear(); for (int i = 0; i < postProcessors.Count; i++) { postProcessors[i].Setup(); if (postProcessors[i].IsActive()) { activePostProcessorIndex.Add(i); } } return activePostProcessorIndex.Count != 0; } } }