using CG.Framework; using System; using System.Collections.Generic; using UnityEditor; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; using Object = UnityEngine.Object; //[ExecuteAlways] public class OutLineCameraRender : MonoSingleton { [Range(1.5f, 5.0f)] public float OutLineScale = 2; [Range(0, 3.0f)] public float OutLineStrength = 1; // Camera cam ; // Start is called before the first frame update private OutLineRenderPass outLineRenderPass; void Start() { outLineRenderPass = new OutLineRenderPass(); RenderPipelineManager.beginCameraRendering += BeginCameraRendering; } private void BeginCameraRendering(ScriptableRenderContext arg1, Camera arg2) { if (arg2.cameraType == CameraType.SceneView || arg2.transform.CompareTag("MainCamera")) { outLineRenderPass.renderPassEvent = RenderPassEvent.BeforeRenderingPostProcessing; outLineRenderPass.outLinePam = OutLineSingle.Instance().GetOutLineRenders(); outLineRenderPass.OutLineScale = OutLineScale; outLineRenderPass.OutLineStrength = OutLineStrength; arg2.GetUniversalAdditionalCameraData().scriptableRenderer.EnqueuePass(outLineRenderPass); } } protected override void OnDestroy() { RenderPipelineManager.endCameraRendering -= BeginCameraRendering; if (outLineRenderPass != null) outLineRenderPass.Distory(); base.OnDestroy(); } //private void OnDestroy() //{ // RenderPipelineManager.endCameraRendering -= BeginCameraRendering; // if(outLineRenderPass != null) // outLineRenderPass.Distory(); //} class OutLineRenderPass : ScriptableRenderPass { private RTHandle OutLineTemp; private RTHandle OutLineTemp1; private RTHandle OutLineTemp11; private RTHandle OutLineTemp2; private RTHandle OutLineTemp3; private RTHandle OutLineTemp4; private RTHandle OutLineTemp9; private RTHandle OutLineTemp10; private RTHandle depth; private Material OutMat; private Material OutMatAll; public float OutLineScale; public float OutLineStrength; public List outLinePam = new List(); public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData) { if (OutMat == null) { OutMat = CoreUtils.CreateEngineMaterial("Unlit URP Shader/OutLine"); OutMatAll = CoreUtils.CreateEngineMaterial("Unlit URP Shader/OutLine2"); } RenderTextureDescriptor rtd = renderingData.cameraData.cameraTargetDescriptor; rtd.msaaSamples = 1; rtd.colorFormat = RenderTextureFormat.DefaultHDR; rtd.depthBufferBits = 0; RenderingUtils.ReAllocateIfNeeded(ref OutLineTemp1, rtd, name: "OutLineTemp1"); RenderingUtils.ReAllocateIfNeeded(ref OutLineTemp11, rtd, name: "OutLineTemp11"); RenderingUtils.ReAllocateIfNeeded(ref OutLineTemp, rtd, name: "OutLineTemp"); rtd.depthBufferBits = 32; rtd.colorFormat = RenderTextureFormat.Depth; RenderingUtils.ReAllocateIfNeeded(ref depth, rtd, name: "depth"); rtd.colorFormat = RenderTextureFormat.DefaultHDR; rtd.depthBufferBits = 0; rtd.width /= 2; rtd.height /= 2; RenderingUtils.ReAllocateIfNeeded(ref OutLineTemp2, rtd, name: "OutLineTemp2"); RenderingUtils.ReAllocateIfNeeded(ref OutLineTemp10, rtd, name: "OutLineTemp10"); rtd.width /= 2; rtd.height /= 2; RenderingUtils.ReAllocateIfNeeded(ref OutLineTemp3, rtd, name: "OutLineTemp3"); RenderingUtils.ReAllocateIfNeeded(ref OutLineTemp9, rtd, name: "OutLineTemp9"); rtd.width /= 2; rtd.height /= 2; RenderingUtils.ReAllocateIfNeeded(ref OutLineTemp4, rtd, name: "OutLineTemp4"); ConfigureTarget(OutLineTemp, depth); ConfigureClear(ClearFlag.All, Vector4.zero); } public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) { CommandBuffer cmd = CommandBufferPool.Get("OutLine"); cmd.SetGlobalVector("_HeightLightColor", Vector4.one); if (outLinePam.Count == 0) return; for (int i = 0; i < outLinePam.Count; i++) { if (outLinePam[i].renders == null || outLinePam[i].renders.Length == 0 || outLinePam[i].draw.color == Color.black) continue; cmd.SetGlobalColor("_OutLineColor", outLinePam[i].draw.color); for (int j = 0; j < outLinePam[i].renders.Length; j++) { if (outLinePam[i].renders[j] == null) continue; cmd.DrawRenderer(outLinePam[i].renders[j], OutMat, 0); } } //高亮范围 cmd.SetGlobalFloat("Scale", OutLineScale); cmd.SetGlobalFloat("Strength", OutLineStrength); //降采样 Blitter.BlitCameraTexture(cmd, OutLineTemp, OutLineTemp2, OutMatAll, 1); Blitter.BlitCameraTexture(cmd, OutLineTemp2, OutLineTemp3, OutMatAll, 1); Blitter.BlitCameraTexture(cmd, OutLineTemp3, OutLineTemp4, OutMatAll, 1); //升采样 cmd.SetGlobalTexture("_Temp", OutLineTemp3); Blitter.BlitCameraTexture(cmd, OutLineTemp4, OutLineTemp9, OutMatAll, 2); cmd.SetGlobalTexture("_Temp", OutLineTemp2); Blitter.BlitCameraTexture(cmd, OutLineTemp9, OutLineTemp10, OutMatAll, 2); cmd.SetGlobalTexture("_Temp", OutLineTemp); Blitter.BlitCameraTexture(cmd, OutLineTemp10, OutLineTemp1, OutMatAll, 2); //全采样进行一次模糊 cmd.SetGlobalFloat("Scale", 3); Blitter.BlitCameraTexture(cmd, OutLineTemp1, OutLineTemp11, OutMatAll, 1); Blitter.BlitCameraTexture(cmd, OutLineTemp11, OutLineTemp, OutMatAll, 1); //3、通过模板测试裁剪描边内部像素 cmd.SetRenderTarget(OutLineTemp, depth); Blitter.BlitTexture(cmd, OutLineTemp1, new Vector4(1, 1, 0, 0), OutMatAll, 3); //4、混合颜色,顺便再模糊一次 Blitter.BlitCameraTexture(cmd, OutLineTemp, renderingData.cameraData.renderer.cameraColorTargetHandle, OutMatAll, 4); context.ExecuteCommandBuffer(cmd); cmd.Release(); } public void Distory() { #if UNITY_EDITOR if (EditorApplication.isPlaying) { Object.Destroy(OutMat); Object.Destroy(OutMatAll); } else { Object.DestroyImmediate(OutMat); Object.DestroyImmediate(OutMatAll); } #else Object.Destroy(OutMat); Object.Destroy(OutMatAll); #endif if (OutLineTemp != null) OutLineTemp.Release(); if (OutLineTemp11 != null) OutLineTemp11.Release(); if (OutLineTemp1 != null) OutLineTemp1.Release(); if (OutLineTemp2 != null) OutLineTemp2.Release(); if (OutLineTemp3 != null) OutLineTemp3.Release(); if (OutLineTemp4 != null) OutLineTemp4.Release(); if (OutLineTemp9 != null) OutLineTemp9.Release(); if (OutLineTemp10 != null) OutLineTemp10.Release(); if (depth != null) depth.Release(); } } }