using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.RendererUtils; using UnityEngine.Rendering.Universal; namespace Gameplay.PostProcess.BlackArea { public class BlackAreaRPF : ScriptableRendererFeature { [System.Serializable] public class Settings { //渲染发生的阶段,具体信息可以在枚举类RenderPassEvent中查看 public RenderPassEvent renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing; public LayerMask layerMask; public Material blitMaterial; } class CustomRenderPass : ScriptableRenderPass { private Settings _settings; private RenderTexture _cachedTarget; private readonly ShaderTagId _shaderTagId = new ShaderTagId("LightArea"); private Material _blitMaterial; public CustomRenderPass(Settings settings) { _settings = settings; _blitMaterial = Instantiate(settings.blitMaterial); } public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData) { base.OnCameraSetup(cmd, ref renderingData); // 只对主相机Camera.main生效 if (renderingData.cameraData.camera != Camera.main) return; if (!BlackAreaManager.instance.enableBlackArea) return; // 创建一个RenderTexture _cachedTarget = RenderTexture.GetTemporary(renderingData.cameraData.camera.pixelWidth, renderingData.cameraData.camera.pixelHeight, 32); } public override void OnCameraCleanup(CommandBuffer cmd) { base.OnCameraCleanup(cmd); if (_cachedTarget != null) { RenderTexture.ReleaseTemporary(_cachedTarget); _cachedTarget = null; } } public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) { // 只对主相机Camera.main生效 if (renderingData.cameraData.camera != Camera.main) return; if (!BlackAreaManager.instance.enableBlackArea) return; var cmd = CommandBufferPool.Get("BlackArea-DrawMask"); cmd.Clear(); cmd.SetRenderTarget(_cachedTarget); // 刷一个黑色背景 cmd.ClearRenderTarget(true, true, Color.black); // 渲染光亮区域 var renderListDesc = new RendererListDesc(_shaderTagId, renderingData.cullResults, renderingData.cameraData.camera); renderListDesc.renderQueueRange = RenderQueueRange.all; renderListDesc.layerMask = _settings.layerMask; var renderList = context.CreateRendererList(renderListDesc); cmd.DrawRendererList(renderList); context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); // 把这张图渲染到屏幕上 cmd = CommandBufferPool.Get("BlackArea-DrawMaskToScreen"); var cameraRt = renderingData.cameraData.renderer.cameraColorTargetHandle.nameID; _blitMaterial.SetTexture(MaskTex, _cachedTarget); cmd.Blit(cameraRt, cameraRt, _blitMaterial); context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); } } public Settings settings; private CustomRenderPass _scriptablePass; private static readonly int MainTex = Shader.PropertyToID("_MainTex"); private static readonly int MaskTex = Shader.PropertyToID("_MaskTex"); public override void Create() { _scriptablePass = new CustomRenderPass(settings); _scriptablePass.renderPassEvent = settings.renderPassEvent; } public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) { renderer.EnqueuePass(_scriptablePass); } } }