123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554 |
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Linq;
- using UnityEngine;
- using UnityEngine.Rendering;
- using UnityEngine.Serialization;
- namespace EPOOutline
- {
- public enum DilateQuality
- {
- Base,
- High,
- Ultra
- }
- public enum RenderingMode
- {
- LDR,
- HDR
- }
- public enum OutlineRenderingStrategy
- {
- Default,
- PerObject
- }
- public enum RenderStage
- {
- BeforeTransparents,
- AfterTransparents
- }
- public enum BufferSizeMode
- {
- WidthControllsHeight,
- HeightControlsWidth,
- Scaled,
- Native
- }
- [ExecuteAlways]
- [RequireComponent(typeof(Camera))]
- public class Outliner : MonoBehaviour
- {
- #if UNITY_EDITOR
- private static GameObject lastSelectedOutliner;
- private static List<Outliner> outliners = new List<Outliner>();
- #endif
- private static List<Outlinable> temporaryOutlinables = new List<Outlinable>();
- private OutlineParameters parameters = new OutlineParameters();
- #if UNITY_EDITOR
- private OutlineParameters editorPreviewParameters = new OutlineParameters();
- #endif
- private Camera targetCamera;
- [SerializeField]
- private RenderStage stage = RenderStage.AfterTransparents;
- [SerializeField]
- private OutlineRenderingStrategy renderingStrategy = OutlineRenderingStrategy.Default;
- [SerializeField]
- private RenderingMode renderingMode;
- [SerializeField]
- private long outlineLayerMask = -1;
- [SerializeField]
- private BufferSizeMode primaryBufferSizeMode;
- [SerializeField]
- [Range(0.15f, 1.0f)]
- private float primaryRendererScale = 0.75f;
- [SerializeField]
- private int primarySizeReference = 800;
- [SerializeField]
- [Range(0.0f, 2.0f)]
- private float blurShift = 1.0f;
- [SerializeField]
- [Range(0.0f, 2.0f)]
- private float dilateShift = 1.0f;
- [SerializeField]
- [FormerlySerializedAs("dilateIterrations")]
- private int dilateIterations = 1;
- [SerializeField]
- private DilateQuality dilateQuality;
- [SerializeField]
- [FormerlySerializedAs("blurIterrations")]
- private int blurIterations = 1;
- [SerializeField]
- private BlurType blurType = BlurType.Box;
- [Obsolete]
- public float InfoRendererScale
- {
- get
- {
- throw new NotImplementedException();
- }
- set
- {
- throw new NotImplementedException();
- }
- }
-
- public int PrimarySizeReference
- {
- get
- {
- return primarySizeReference;
- }
- set
- {
- primarySizeReference = value;
- }
- }
- public BufferSizeMode PrimaryBufferSizeMode
- {
- get
- {
- return primaryBufferSizeMode;
- }
- set
- {
- primaryBufferSizeMode = value;
- }
- }
- private CameraEvent Event
- {
- get
- {
- return stage == RenderStage.BeforeTransparents ? CameraEvent.AfterForwardOpaque : CameraEvent.BeforeImageEffects;
- }
- }
- public OutlineRenderingStrategy RenderingStrategy
- {
- get
- {
- return renderingStrategy;
- }
- set
- {
- renderingStrategy = value;
- }
- }
- public RenderStage RenderStage
- {
- get
- {
- return stage;
- }
- set
- {
- stage = value;
- }
- }
- public DilateQuality DilateQuality
- {
- get
- {
- return dilateQuality;
- }
- set
- {
- dilateQuality = value;
- }
- }
- private RenderingMode RenderingMode
- {
- get
- {
- return renderingMode;
- }
- set
- {
- renderingMode = value;
- }
- }
- public float BlurShift
- {
- get
- {
- return blurShift;
- }
- set
- {
- blurShift = Mathf.Clamp(value, 0, 2.0f);
- }
- }
- public float DilateShift
- {
- get
- {
- return dilateShift;
- }
- set
- {
- dilateShift = Mathf.Clamp(value, 0, 2.0f);
- }
- }
- public long OutlineLayerMask
- {
- get
- {
- return outlineLayerMask;
- }
- set
- {
- outlineLayerMask = value;
- }
- }
- public float PrimaryRendererScale
- {
- get
- {
- return primaryRendererScale;
- }
- set
- {
- primaryRendererScale = Mathf.Clamp01(value);
- }
- }
- [Obsolete("Fixed incorrect spelling. Use BlurIterations instead")]
- public int BlurIterrations
- {
- get
- {
- return BlurIterations;
- }
- set
- {
- BlurIterations = value;
- }
- }
- public int BlurIterations
- {
- get
- {
- return blurIterations;
- }
- set
- {
- blurIterations = value > 0 ? value : 0;
- }
- }
- public BlurType BlurType
- {
- get
- {
- return blurType;
- }
- set
- {
- blurType = value;
- }
- }
- [Obsolete("Fixed incorrect spelling. Use DilateIterations instead")]
- public int DilateIterration
- {
- get
- {
- return DilateIterations;
- }
- set
- {
- DilateIterations = value;
- }
- }
- public int DilateIterations
- {
- get
- {
- return dilateIterations;
- }
- set
- {
- dilateIterations = value > 0 ? value : 0;
- }
- }
- private void OnValidate()
- {
- if (blurIterations < 0)
- blurIterations = 0;
- if (dilateIterations < 0)
- dilateIterations = 0;
- }
- private void OnEnable()
- {
- if (targetCamera == null)
- targetCamera = GetComponent<Camera>();
- targetCamera.forceIntoRenderTexture = targetCamera.stereoTargetEye == StereoTargetEyeMask.None || !UnityEngine.XR.XRSettings.enabled;
- #if UNITY_EDITOR
- outliners.Add(this);
- #endif
- parameters.CheckInitialization();
- parameters.Buffer.name = "Outline";
- #if UNITY_EDITOR
- editorPreviewParameters.CheckInitialization();
- editorPreviewParameters.Buffer.name = "Editor outline";
- #endif
- }
- private void OnDestroy()
- {
- #if UNITY_EDITOR
- GameObject.DestroyImmediate(editorPreviewParameters.BlitMesh);
- if (editorPreviewParameters.Buffer != null)
- editorPreviewParameters.Buffer.Dispose();
- #endif
- GameObject.DestroyImmediate(parameters.BlitMesh);
- if (parameters.Buffer != null)
- parameters.Buffer.Dispose();
- }
- private void OnDisable()
- {
- if (targetCamera != null)
- UpdateBuffer(targetCamera, parameters.Buffer, true);
- #if UNITY_EDITOR
- RemoveFromAllSceneViews();
- outliners.Remove(this);
- #endif
- #if UNITY_EDITOR
- foreach (var view in UnityEditor.SceneView.sceneViews)
- {
- var viewToUpdate = (UnityEditor.SceneView)view;
- viewToUpdate.camera.RemoveCommandBuffer(CameraEvent.BeforeImageEffects, editorPreviewParameters.Buffer);
- viewToUpdate.camera.RemoveCommandBuffer(CameraEvent.AfterForwardOpaque, editorPreviewParameters.Buffer);
- }
- #endif
- }
- private void UpdateBuffer(Camera targetCamera, CommandBuffer buffer, bool removeOnly)
- {
- targetCamera.RemoveCommandBuffer(CameraEvent.BeforeImageEffects, buffer);
- targetCamera.RemoveCommandBuffer(CameraEvent.AfterForwardOpaque, buffer);
- if (removeOnly)
- return;
- targetCamera.AddCommandBuffer(Event, buffer);
- }
- private void OnPreRender()
- {
- if (GraphicsSettings.renderPipelineAsset != null)
- return;
- parameters.OutlinablesToRender.Clear();
- SetupOutline(targetCamera, parameters, false);
- }
- private void SetupOutline(Camera cameraToUse, OutlineParameters parametersToUse, bool isEditor)
- {
- UpdateBuffer(cameraToUse, parametersToUse.Buffer, false);
- UpdateParameters(parametersToUse, cameraToUse, isEditor);
- parametersToUse.Buffer.Clear();
- if (renderingStrategy == OutlineRenderingStrategy.Default)
- {
- OutlineEffect.SetupOutline(parametersToUse);
- parametersToUse.BlitMesh = null;
- parametersToUse.MeshPool.ReleaseAllMeshes();
- }
- else
- {
- temporaryOutlinables.Clear();
- temporaryOutlinables.AddRange(parametersToUse.OutlinablesToRender);
- parametersToUse.OutlinablesToRender.Clear();
- parametersToUse.OutlinablesToRender.Add(null);
- foreach (var outlinable in temporaryOutlinables)
- {
- parametersToUse.OutlinablesToRender[0] = outlinable;
- OutlineEffect.SetupOutline(parametersToUse);
- parametersToUse.BlitMesh = null;
- }
- parametersToUse.MeshPool.ReleaseAllMeshes();
- }
- }
- #if UNITY_EDITOR
- private void RemoveFromAllSceneViews()
- {
- foreach (var view in UnityEditor.SceneView.sceneViews)
- {
- var viewToUpdate = (UnityEditor.SceneView)view;
- var eventTransferer = viewToUpdate.camera.GetComponent<OnPreRenderEventTransferer>();
- if (eventTransferer != null)
- eventTransferer.OnPreRenderEvent -= UpdateEditorCamera;
- viewToUpdate.camera.RemoveCommandBuffer(CameraEvent.BeforeImageEffects, editorPreviewParameters.Buffer);
- viewToUpdate.camera.RemoveCommandBuffer(CameraEvent.AfterForwardOpaque, editorPreviewParameters.Buffer);
- }
- }
- private void LateUpdate()
- {
- if (lastSelectedOutliner == null && outliners.Count > 0)
- lastSelectedOutliner = outliners[0].gameObject;
- var isSelected = Array.Find(UnityEditor.Selection.gameObjects, x => x == gameObject) ?? lastSelectedOutliner != null;
- if (isSelected)
- lastSelectedOutliner = gameObject;
- foreach (var view in UnityEditor.SceneView.sceneViews)
- {
- var viewToUpdate = (UnityEditor.SceneView)view;
- var eventTransferer = viewToUpdate.camera.GetComponent<OnPreRenderEventTransferer>();
- if (eventTransferer != null)
- eventTransferer.OnPreRenderEvent -= UpdateEditorCamera;
- UpdateBuffer(viewToUpdate.camera, editorPreviewParameters.Buffer, true);
- }
- if (!isSelected)
- return;
- foreach (var view in UnityEditor.SceneView.sceneViews)
- {
- var viewToUpdate = (UnityEditor.SceneView)view;
- if (!viewToUpdate.sceneViewState.showImageEffects)
- continue;
- var eventTransferer = viewToUpdate.camera.GetComponent<OnPreRenderEventTransferer>();
- if (eventTransferer == null)
- eventTransferer = viewToUpdate.camera.gameObject.AddComponent<OnPreRenderEventTransferer>();
- eventTransferer.OnPreRenderEvent += UpdateEditorCamera;
- }
- }
- private void UpdateEditorCamera(Camera camera)
- {
- SetupOutline(camera, editorPreviewParameters, true);
- }
- #endif
- public void UpdateSharedParameters(OutlineParameters parameters, Camera camera, bool editorCamera)
- {
- parameters.DilateQuality = DilateQuality;
- parameters.Camera = camera;
- parameters.IsEditorCamera = editorCamera;
- parameters.PrimaryBufferScale = primaryRendererScale;
- parameters.PrimaryBufferSizeMode = primaryBufferSizeMode;
- parameters.PrimaryBufferSizeReference = primarySizeReference;
- parameters.BlurIterations = blurIterations;
- parameters.BlurType = blurType;
- parameters.DilateIterations = dilateIterations;
- parameters.BlurShift = blurShift;
- parameters.DilateShift = dilateShift;
- parameters.UseHDR = camera.allowHDR && (RenderingMode == RenderingMode.HDR);
- parameters.EyeMask = camera.stereoTargetEye;
- parameters.OutlineLayerMask = outlineLayerMask;
- parameters.Prepare();
- }
- private void UpdateParameters(OutlineParameters parameters, Camera camera, bool editorCamera)
- {
- parameters.DepthTarget = RenderTargetUtility.ComposeTarget(parameters, BuiltinRenderTextureType.CameraTarget);
- var targetTexture = camera.targetTexture == null ? camera.activeTexture : camera.targetTexture;
- if (UnityEngine.XR.XRSettings.enabled
- && !parameters.IsEditorCamera
- && parameters.EyeMask != StereoTargetEyeMask.None)
- {
- var descriptor = UnityEngine.XR.XRSettings.eyeTextureDesc;
- parameters.TargetWidth = descriptor.width;
- parameters.TargetHeight = descriptor.height;
- }
- else
- {
- parameters.TargetWidth = targetTexture != null ? targetTexture.width : camera.scaledPixelWidth;
- parameters.TargetHeight = targetTexture != null ? targetTexture.height : camera.scaledPixelHeight;
- }
- parameters.Antialiasing = editorCamera ? (targetTexture == null ? 1 : targetTexture.antiAliasing) : CameraUtility.GetMSAA(targetCamera);
- parameters.Target = RenderTargetUtility.ComposeTarget(parameters, BuiltinRenderTextureType.CameraTarget);
- parameters.Camera = camera;
- Outlinable.GetAllActiveOutlinables(parameters.Camera, parameters.OutlinablesToRender);
- RendererFilteringUtility.Filter(parameters.Camera, parameters);
- UpdateSharedParameters(parameters, camera, editorCamera);
- }
- }
- }
|