123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEngine.Rendering;
- using EPOOutline;
- using System;
- using System.Reflection;
- #if URP_OUTLINE && UNITY_2019_1_OR_NEWER
- #if UNITY_2019_3_OR_NEWER
- using UnityEngine.Rendering.Universal;
- #else
- using UnityEngine.Rendering.LWRP;
- #endif
- public class URPOutlineFeature : ScriptableRendererFeature
- {
- private class SRPOutline : ScriptableRenderPass
- {
- private static List<Outlinable> temporaryOutlinables = new List<Outlinable>();
- public ScriptableRenderer Renderer;
- public bool UseColorTargetForDepth;
- public Outliner Outliner;
- public OutlineParameters Parameters = new OutlineParameters();
- private List<Outliner> outliners = new List<Outliner>();
- public SRPOutline()
- {
- Parameters.CheckInitialization();
- }
- private FieldInfo nameId = typeof(RenderTargetIdentifier).GetField("m_NameID", BindingFlags.NonPublic | BindingFlags.Instance);
- private bool IsDepthTextureAvailable(ScriptableRenderer renderer)
- {
- #if UNITY_2022_1_OR_NEWER
- return renderer.cameraDepthTargetHandle.rt != null;
- #else
- return (int)nameId.GetValue(GetDepthTarget(renderer)) != -1;
- #endif
- }
- private RenderTargetIdentifier GetDepthTarget(ScriptableRenderer renderer)
- {
- return
- #if UNITY_2022_1_OR_NEWER
- Renderer.cameraDepthTargetHandle;
- #elif UNITY_2020_2_OR_NEWER
- Renderer.cameraDepthTarget;
- #else
- Renderer.cameraDepth;
- #endif
- }
- private RenderTargetIdentifier GetColorTarget(ScriptableRenderer renderer)
- {
- #if UNITY_2022_1_OR_NEWER
- return renderer.cameraColorTargetHandle;
- #else
- return renderer.cameraColorTarget;
- #endif
- }
- public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
- {
- var camera = renderingData.cameraData.camera;
- var outlineEffect = Outliner;
- if (outlineEffect == null || !outlineEffect.enabled)
- return;
- #if UNITY_EDITOR
- Parameters.Buffer.name = renderingData.cameraData.camera.name;
- #endif
- Outlinable.GetAllActiveOutlinables(renderingData.cameraData.camera, Parameters.OutlinablesToRender);
- Outliner.UpdateSharedParameters(Parameters, renderingData.cameraData.camera, renderingData.cameraData.isSceneViewCamera);
- RendererFilteringUtility.Filter(renderingData.cameraData.camera, Parameters);
- Parameters.TargetWidth = renderingData.cameraData.cameraTargetDescriptor.width;
- Parameters.TargetHeight = renderingData.cameraData.cameraTargetDescriptor.height;
- Parameters.Antialiasing = renderingData.cameraData.cameraTargetDescriptor.msaaSamples;
- Parameters.Target = RenderTargetUtility.ComposeTarget(Parameters, Renderer.cameraColorTarget);
- Parameters.DepthTarget =
- #if UNITY_2019_3_OR_NEWER && !UNITY_2019_3_0 && !UNITY_2019_3_1 && !UNITY_2019_3_2 && !UNITY_2019_3_3 && !UNITY_2019_3_4 && !UNITY_2019_3_5 && !UNITY_2019_3_6 && !UNITY_2019_3_7 && !UNITY_2019_3_8
- RenderTargetUtility.ComposeTarget(Parameters, !IsDepthTextureAvailable(Renderer) ? GetColorTarget(Renderer) :
- GetDepthTarget(Renderer));
- #else
- RenderTargetUtility.ComposeTarget(Parameters, Renderer.cameraColorTarget);
- #endif
- Parameters.Buffer.Clear();
- if (Outliner.RenderingStrategy == OutlineRenderingStrategy.Default)
- {
- OutlineEffect.SetupOutline(Parameters);
- Parameters.BlitMesh = null;
- Parameters.MeshPool.ReleaseAllMeshes();
- }
- else
- {
- temporaryOutlinables.Clear();
- temporaryOutlinables.AddRange(Parameters.OutlinablesToRender);
- Parameters.OutlinablesToRender.Clear();
- Parameters.OutlinablesToRender.Add(null);
- foreach (var outlinable in temporaryOutlinables)
- {
- Parameters.OutlinablesToRender[0] = outlinable;
- OutlineEffect.SetupOutline(Parameters);
- Parameters.BlitMesh = null;
- }
- Parameters.MeshPool.ReleaseAllMeshes();
- }
- context.ExecuteCommandBuffer(Parameters.Buffer);
- }
- }
- private class Pool
- {
- private Stack<SRPOutline> outlines = new Stack<SRPOutline>();
- private List<SRPOutline> createdOutlines = new List<SRPOutline>();
- public SRPOutline Get()
- {
- if (outlines.Count == 0)
- {
- outlines.Push(new SRPOutline());
- createdOutlines.Add(outlines.Peek());
- }
- return outlines.Pop();
- }
- public void ReleaseAll()
- {
- outlines.Clear();
- foreach (var outline in createdOutlines)
- outlines.Push(outline);
- }
- }
- private GameObject lastSelectedCamera;
- private Pool outlinePool = new Pool();
- private List<Outliner> outliners = new List<Outliner>();
- private bool GetOutlinersToRenderWith(RenderingData renderingData, List<Outliner> outliners)
- {
- outliners.Clear();
- var camera = renderingData.cameraData.camera.gameObject;
- camera.GetComponents(outliners);
- if (outliners.Count == 0)
- {
- #if UNITY_EDITOR
- if (renderingData.cameraData.isSceneViewCamera)
- {
- var foundObject = Array.Find(
- Array.ConvertAll(UnityEditor.Selection.gameObjects, x => x.GetComponent<Outliner>()),
- x => x != null);
- camera = foundObject?.gameObject ?? lastSelectedCamera;
- if (camera == null)
- return false;
- else
- camera.GetComponents(outliners);
- }
- else
- return false;
- #else
- return false;
- #endif
- }
- var hasOutliners = outliners.Count > 0;
- if (hasOutliners)
- lastSelectedCamera = camera;
- return hasOutliners;
- }
- public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
- {
- if (!GetOutlinersToRenderWith(renderingData, outliners))
- return;
- #if UNITY_2019_3_OR_NEWER && !UNITY_2019_3_0 && !UNITY_2019_3_1 && !UNITY_2019_3_2 && !UNITY_2019_3_3 && !UNITY_2019_3_4 && !UNITY_2019_3_5 && !UNITY_2019_3_6 && !UNITY_2019_3_7 && !UNITY_2019_3_8
- var additionalCameraData = renderingData.cameraData.camera.GetUniversalAdditionalCameraData();
- var activeStackCount = 0;
- if (additionalCameraData != null)
- {
- var stack = additionalCameraData.renderType == CameraRenderType.Overlay ? null : additionalCameraData.cameraStack;
- if (stack != null)
- {
- foreach (var camera in stack)
- {
- if (camera != null && camera.isActiveAndEnabled)
- activeStackCount++;
- }
- }
- }
- #endif
- foreach (var outliner in outliners)
- {
- var outline = outlinePool.Get();
- outline.Outliner = outliner;
- outline.Renderer = renderer;
- outline.renderPassEvent = outliner.RenderStage == RenderStage.AfterTransparents ? RenderPassEvent.AfterRenderingTransparents : RenderPassEvent.AfterRenderingOpaques;
- renderer.EnqueuePass(outline);
- }
- outlinePool.ReleaseAll();
- }
- public override void Create()
- {
- }
- }
- #endif
|