using System.Collections.Generic; using System.Linq; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; namespace SLSFramework.Rendering.PostProcessing { public class ScriptablePostProcessorFeature : ScriptableRendererFeature { private List postProcessorVolumes; private ScriptablePostProcessorPass afterTransparentPass; private ScriptablePostProcessorPass beforePostProcessPass; private ScriptablePostProcessorPass afterPostProcessPass; public override void Create() { var stack = VolumeManager.instance.stack; postProcessorVolumes = VolumeManager.instance.baseComponentTypeArray .Where(t => t.IsSubclassOf(typeof(ScriptablePostProcessorVolume))) .Select(t => stack.GetComponent(t) as ScriptablePostProcessorVolume) .ToList(); var afterTransparentPostProcessors = postProcessorVolumes .Where(c => c.InjectionPoint == CustomPostProcessInjectionPoint.AfterTransparent) .OrderBy(c => c.OrderInInjectionPoint) .ToList(); afterTransparentPass = new ScriptablePostProcessorPass("Custom PostProcessor - after Transparent", afterTransparentPostProcessors) { renderPassEvent = RenderPassEvent.AfterRenderingTransparents }; var beforePostProcessPostProcessors = postProcessorVolumes .Where(c => c.InjectionPoint == CustomPostProcessInjectionPoint.BeforePostProcess) .OrderBy(c => c.OrderInInjectionPoint) .ToList(); beforePostProcessPass = new ScriptablePostProcessorPass("Custom PostProcessor - before PostProcessing", beforePostProcessPostProcessors) { renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing }; var afterPostProcessPostProcessors = postProcessorVolumes .Where(c => c.InjectionPoint == CustomPostProcessInjectionPoint.AfterPostProcess) .OrderBy(c => c.OrderInInjectionPoint) .ToList(); afterPostProcessPass = new ScriptablePostProcessorPass("Custom PostProcessor - after PostProcessing", afterPostProcessPostProcessors) { renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing }; } public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) { // 只有在相机开启后处理时才执行 if (renderingData.cameraData.postProcessEnabled) { // 关键点:将 renderingData 传递给 Pass 的 Setup 方法 // 这样我们就能把数据缓存下来给 RenderGraph 使用了 if (afterTransparentPass.Setup(ref renderingData)) { afterTransparentPass.ConfigureInput(ScriptableRenderPassInput.Color); renderer.EnqueuePass(afterTransparentPass); } if (beforePostProcessPass.Setup(ref renderingData)) { beforePostProcessPass.ConfigureInput(ScriptableRenderPassInput.Color); renderer.EnqueuePass(beforePostProcessPass); } if (afterPostProcessPass.Setup(ref renderingData)) { afterPostProcessPass.ConfigureInput(ScriptableRenderPassInput.Color); renderer.EnqueuePass(afterPostProcessPass); } } } protected override void Dispose(bool disposing) { base.Dispose(disposing); if (disposing) { if (postProcessorVolumes != null) { foreach (var item in postProcessorVolumes) { item.Dispose(); } } afterTransparentPass = null; beforePostProcessPass = null; afterPostProcessPass = null; } } } }