634 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C#
		
	
	
	
			
		
		
	
	
			634 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C#
		
	
	
	
| using UnityEngine;
 | |
| using UnityEngine.Rendering;
 | |
| using UnityEngine.Serialization;
 | |
| using UnityEngine.XR;
 | |
| using System.Collections;
 | |
| using System.Collections.Generic;
 | |
| #if UNITY_5_5_OR_NEWER
 | |
| using UnityEngine.Profiling;
 | |
| #endif
 | |
| 
 | |
| namespace HighlightingSystem
 | |
| {
 | |
| 	public enum BlurDirections : int
 | |
| 	{
 | |
| 		Diagonal, 
 | |
| 		Straight, 
 | |
| 		All
 | |
| 	}
 | |
| 
 | |
| 	public enum AntiAliasing : int
 | |
| 	{
 | |
| 		QualitySettings, 
 | |
| 		Disabled, 
 | |
| 		MSAA2x, 
 | |
| 		MSAA4x, 
 | |
| 		MSAA8x, 
 | |
| 	}
 | |
| 
 | |
| 	[DisallowMultipleComponent]
 | |
| 	[RequireComponent(typeof(Camera))]
 | |
| 	public class HighlightingBase : MonoBehaviour
 | |
| 	{
 | |
| 		#region Static Fields and Constants
 | |
| 		static protected readonly Color colorClear = new Color(0f, 0f, 0f, 0f);
 | |
| 		static protected readonly string renderBufferName = "HighlightingSystem";
 | |
| 		static protected readonly Matrix4x4 identityMatrix = Matrix4x4.identity;
 | |
| 		static protected readonly string keywordStraightDirections = "STRAIGHT_DIRECTIONS";
 | |
| 		static protected readonly string keywordAllDirections = "ALL_DIRECTIONS";
 | |
| 		static protected readonly string profileHighlightingSystem = "HighlightingSystem";
 | |
| 		protected const CameraEvent queue = CameraEvent.BeforeImageEffectsOpaque;
 | |
| 
 | |
| 		static protected Camera currentCamera;
 | |
| 		static protected HashSet<HighlighterRenderer> visibleRenderers = new HashSet<HighlighterRenderer>();
 | |
| 		#endregion
 | |
| 		
 | |
| 		#region Accessors
 | |
| 		// True if supported on this platform
 | |
| 		public bool isSupported
 | |
| 		{
 | |
| 			get
 | |
| 			{
 | |
| 				return CheckSupported(false);
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		public float fillAlpha
 | |
| 		{
 | |
| 			get { return _fillAlpha; }
 | |
| 			set
 | |
| 			{
 | |
| 				value = Mathf.Clamp01(value);
 | |
| 				if (_fillAlpha != value)
 | |
| 				{
 | |
| 					if (Application.isPlaying)
 | |
| 					{
 | |
| 						cutMaterial.SetFloat(ShaderPropertyID._HighlightingFillAlpha, value);
 | |
| 					}
 | |
| 
 | |
| 					_fillAlpha = value;
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		// Highlighting buffer size downsample factor
 | |
| 		public int downsampleFactor
 | |
| 		{
 | |
| 			get { return _downsampleFactor; }
 | |
| 			set
 | |
| 			{
 | |
| 				if (_downsampleFactor != value)
 | |
| 				{
 | |
| 					// Is power of two check
 | |
| 					if ((value != 0) && ((value & (value - 1)) == 0))
 | |
| 					{
 | |
| 						_downsampleFactor = value;
 | |
| 					}
 | |
| 					else
 | |
| 					{
 | |
| 						Debug.LogWarning("HighlightingSystem : Prevented attempt to set incorrect downsample factor value.");
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		
 | |
| 		// Blur iterations
 | |
| 		public int iterations
 | |
| 		{
 | |
| 			get { return _iterations; }
 | |
| 			set
 | |
| 			{
 | |
| 				if (_iterations != value)
 | |
| 				{
 | |
| 					_iterations = value;
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		
 | |
| 		// Blur minimal spread
 | |
| 		public float blurMinSpread
 | |
| 		{
 | |
| 			get { return _blurMinSpread; }
 | |
| 			set
 | |
| 			{
 | |
| 				if (_blurMinSpread != value)
 | |
| 				{
 | |
| 					_blurMinSpread = value;
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		
 | |
| 		// Blur spread per iteration
 | |
| 		public float blurSpread
 | |
| 		{
 | |
| 			get { return _blurSpread; }
 | |
| 			set
 | |
| 			{
 | |
| 				if (_blurSpread != value)
 | |
| 				{
 | |
| 					_blurSpread = value;
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		
 | |
| 		// Blurring intensity for the blur material
 | |
| 		public float blurIntensity
 | |
| 		{
 | |
| 			get { return _blurIntensity; }
 | |
| 			set
 | |
| 			{
 | |
| 				if (_blurIntensity != value)
 | |
| 				{
 | |
| 					_blurIntensity = value;
 | |
| 					if (Application.isPlaying)
 | |
| 					{
 | |
| 						blurMaterial.SetFloat(ShaderPropertyID._HighlightingIntensity, _blurIntensity);
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		public BlurDirections blurDirections
 | |
| 		{
 | |
| 			get { return _blurDirections; }
 | |
| 			set
 | |
| 			{
 | |
| 				if (_blurDirections != value)
 | |
| 				{
 | |
| 					_blurDirections = value;
 | |
| 					if (Application.isPlaying)
 | |
| 					{
 | |
| 						blurMaterial.SetKeyword(keywordStraightDirections, _blurDirections == BlurDirections.Straight);
 | |
| 						blurMaterial.SetKeyword(keywordAllDirections, _blurDirections == BlurDirections.All);
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		// Blitter component reference (optional)
 | |
| 		public HighlightingBlitter blitter
 | |
| 		{
 | |
| 			get { return _blitter; }
 | |
| 			set
 | |
| 			{
 | |
| 				if (_blitter != value)
 | |
| 				{
 | |
| 					if (_blitter != null)
 | |
| 					{
 | |
| 						_blitter.Unregister(this);
 | |
| 					}
 | |
| 					_blitter = value;
 | |
| 					if (_blitter != null)
 | |
| 					{
 | |
| 						_blitter.Register(this);
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		public AntiAliasing antiAliasing
 | |
| 		{
 | |
| 			get { return _antiAliasing; }
 | |
| 			set
 | |
| 			{
 | |
| 				if (_antiAliasing != value)
 | |
| 				{
 | |
| 					_antiAliasing = value;
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		#endregion
 | |
| 		
 | |
| 		#region Protected Fields
 | |
| 		protected CommandBuffer renderBuffer;
 | |
| 
 | |
| 		protected RenderTextureDescriptor cachedDescriptor;
 | |
| 
 | |
| 		[SerializeField]
 | |
| 		protected float _fillAlpha = 0f;
 | |
| 
 | |
| 		[FormerlySerializedAs("downsampleFactor")]
 | |
| 		[SerializeField]
 | |
| 		protected int _downsampleFactor = 4;
 | |
| 
 | |
| 		[FormerlySerializedAs("iterations")]
 | |
| 		[SerializeField]
 | |
| 		protected int _iterations = 2;
 | |
| 
 | |
| 		[FormerlySerializedAs("blurMinSpread")]
 | |
| 		[SerializeField]
 | |
| 		protected float _blurMinSpread = 0.65f;
 | |
| 
 | |
| 		[FormerlySerializedAs("blurSpread")]
 | |
| 		[SerializeField]
 | |
| 		protected float _blurSpread = 0.25f;
 | |
| 
 | |
| 		[SerializeField]
 | |
| 		protected float _blurIntensity = 0.3f;
 | |
| 
 | |
| 		[SerializeField]
 | |
| 		protected BlurDirections _blurDirections = BlurDirections.Diagonal;
 | |
| 
 | |
| 		[SerializeField]
 | |
| 		protected HighlightingBlitter _blitter;
 | |
| 
 | |
| 		[SerializeField]
 | |
| 		protected AntiAliasing _antiAliasing = AntiAliasing.QualitySettings;
 | |
| 
 | |
| 		// RenderTargetidentifier for the highlightingBuffer RenderTexture
 | |
| 		protected RenderTargetIdentifier highlightingBufferID;
 | |
| 		protected RenderTargetIdentifier blur1ID;
 | |
| 		protected RenderTargetIdentifier blur2ID;
 | |
| 
 | |
| 		// RenderTexture with highlighting buffer
 | |
| 		protected RenderTexture highlightingBuffer = null;
 | |
| 
 | |
| 		// Camera reference
 | |
| 		protected Camera cam = null;
 | |
| 
 | |
| 		// Material parameters
 | |
| 		protected const int BLUR = 0;
 | |
| 		protected const int CUT = 1;
 | |
| 		protected const int COMP = 2;
 | |
| 		static protected readonly string[] shaderPaths = new string[]
 | |
| 		{
 | |
| 			"Hidden/Highlighted/Blur", 
 | |
| 			"Hidden/Highlighted/Cut", 
 | |
| 			"Hidden/Highlighted/Composite", 
 | |
| 		};
 | |
| 		static protected Shader[] shaders;
 | |
| 		static protected Material[] materials;
 | |
| 
 | |
| 		// Dynamic materials
 | |
| 		protected Material blurMaterial;
 | |
| 		protected Material cutMaterial;
 | |
| 		protected Material compMaterial;
 | |
| 
 | |
| 		static protected bool initialized = false;
 | |
| 		#endregion
 | |
| 
 | |
| 		#region MonoBehaviour
 | |
| 		// 
 | |
| 		protected virtual void OnEnable()
 | |
| 		{
 | |
| 			Initialize();
 | |
| 
 | |
| 			if (!CheckSupported(true))
 | |
| 			{
 | |
| 				enabled = false;
 | |
| 				Debug.LogError("HighlightingSystem : Highlighting System has been disabled due to unsupported Unity features on the current platform!");
 | |
| 				return;
 | |
| 			}
 | |
| 
 | |
| 			blur1ID = new RenderTargetIdentifier(ShaderPropertyID._HighlightingBlur1);
 | |
| 			blur2ID = new RenderTargetIdentifier(ShaderPropertyID._HighlightingBlur2);
 | |
| 
 | |
| 			blurMaterial = new Material(materials[BLUR]);
 | |
| 			cutMaterial = new Material(materials[CUT]);
 | |
| 			compMaterial = new Material(materials[COMP]);
 | |
| 			
 | |
| 			// Set initial material properties
 | |
| 			blurMaterial.SetKeyword(keywordStraightDirections, _blurDirections == BlurDirections.Straight);
 | |
| 			blurMaterial.SetKeyword(keywordAllDirections, _blurDirections == BlurDirections.All);
 | |
| 			blurMaterial.SetFloat(ShaderPropertyID._HighlightingIntensity, _blurIntensity);
 | |
| 			cutMaterial.SetFloat(ShaderPropertyID._HighlightingFillAlpha, _fillAlpha);
 | |
| 
 | |
| 			renderBuffer = new CommandBuffer();
 | |
| 			renderBuffer.name = renderBufferName;
 | |
| 
 | |
| 			cam = GetComponent<Camera>();
 | |
| 
 | |
| 			cam.depthTextureMode |= DepthTextureMode.Depth;
 | |
| 
 | |
| 			cam.AddCommandBuffer(queue, renderBuffer);
 | |
| 
 | |
| 			if (_blitter != null)
 | |
| 			{
 | |
| 				_blitter.Register(this);
 | |
| 			}
 | |
| 
 | |
| 			EndOfFrame.AddListener(OnEndOfFrame);
 | |
| 		}
 | |
| 		
 | |
| 		// 
 | |
| 		protected virtual void OnDisable()
 | |
| 		{
 | |
| 			if (renderBuffer != null)
 | |
| 			{
 | |
| 				cam.RemoveCommandBuffer(queue, renderBuffer);
 | |
| 				renderBuffer = null;
 | |
| 			}
 | |
| 
 | |
| 			if (highlightingBuffer != null && highlightingBuffer.IsCreated())
 | |
| 			{
 | |
| 				highlightingBuffer.Release();
 | |
| 				highlightingBuffer = null;
 | |
| 			}
 | |
| 
 | |
| 			if (_blitter != null)
 | |
| 			{
 | |
| 				_blitter.Unregister(this);
 | |
| 			}
 | |
| 
 | |
| 			EndOfFrame.RemoveListener(OnEndOfFrame);
 | |
| 		}
 | |
| 
 | |
| 		// 
 | |
| 		protected virtual void OnPreCull()
 | |
| 		{
 | |
| 			currentCamera = cam;
 | |
| 			visibleRenderers.Clear();
 | |
| 		}
 | |
| 
 | |
| 		// 
 | |
| 		protected virtual void OnPreRender()
 | |
| 		{
 | |
| 			Profiler.BeginSample("HighlightingSystem.OnPreRender");
 | |
| 
 | |
| 			var descriptor = GetDescriptor();
 | |
| 
 | |
| 			if (highlightingBuffer == null || !Equals(cachedDescriptor, descriptor))
 | |
| 			{
 | |
| 				if (highlightingBuffer != null)
 | |
| 				{
 | |
| 					if (highlightingBuffer.IsCreated())
 | |
| 					{
 | |
| 						highlightingBuffer.Release();
 | |
| 					}
 | |
| 					highlightingBuffer = null;
 | |
| 				}
 | |
| 
 | |
| 				cachedDescriptor = descriptor;
 | |
| 
 | |
| 				highlightingBuffer = new RenderTexture(cachedDescriptor);
 | |
| 				highlightingBuffer.filterMode = FilterMode.Point;
 | |
| 				highlightingBuffer.wrapMode = TextureWrapMode.Clamp;
 | |
| 
 | |
| 				if (!highlightingBuffer.Create())
 | |
| 				{
 | |
| 					Debug.LogError("HighlightingSystem : UpdateHighlightingBuffer() : Failed to create highlightingBuffer RenderTexture!");
 | |
| 				}
 | |
| 				
 | |
| 				highlightingBufferID = new RenderTargetIdentifier(highlightingBuffer);
 | |
| 				compMaterial.SetTexture(ShaderPropertyID._HighlightingBuffer, highlightingBuffer);
 | |
| 			}
 | |
| 
 | |
| 			RebuildCommandBuffer();
 | |
| 			Profiler.EndSample();
 | |
| 		}
 | |
| 
 | |
| 		// Do not remove! 
 | |
| 		// Having this method in this script is necessary to support multiple cameras with different clear flags even in case custom blitter is being used. 
 | |
| 		// Also, CommandBuffer is bound to CameraEvent.BeforeImageEffectsOpaque event, 
 | |
| 		// so Unity will spam 'depthSurface == NULL || rcolorZero->backBuffer == depthSurface->backBuffer' error even if MSAA is enabled
 | |
| 		protected virtual void OnRenderImage(RenderTexture src, RenderTexture dst)
 | |
| 		{
 | |
| 			Profiler.BeginSample("HighlightingSystem.OnRenderImage");
 | |
| 			if (blitter == null)
 | |
| 			{
 | |
| 				Blit(src, dst);
 | |
| 			}
 | |
| 			else
 | |
| 			{
 | |
| 				Graphics.Blit(src, dst);
 | |
| 			}
 | |
| 			Profiler.EndSample();
 | |
| 		}
 | |
| 
 | |
| 		// 
 | |
| 		protected virtual void OnEndOfFrame()
 | |
| 		{
 | |
| 			currentCamera = null;
 | |
| 			visibleRenderers.Clear();
 | |
| 		}
 | |
| 		#endregion
 | |
| 
 | |
| 		#region Internal
 | |
| 		// 
 | |
| 		[UnityEngine.Internal.ExcludeFromDocs]
 | |
| 		static public void SetVisible(HighlighterRenderer renderer)
 | |
| 		{
 | |
| 			// Another camera may intercept rendering and send it's own OnWillRenderObject events (i.e. water rendering). 
 | |
| 			// Also, VR Camera with Multi Pass Stereo Rendering Method renders twice per frame (once for each eye), 
 | |
| 			// but OnWillRenderObject is called once so we have to check. 
 | |
| 			if (Camera.current != currentCamera) { return; }
 | |
| 
 | |
| 			// Add to the list of renderers visible for the current Highlighting renderer
 | |
| 			visibleRenderers.Add(renderer);
 | |
| 		}
 | |
| 
 | |
| 		// 
 | |
| 		[UnityEngine.Internal.ExcludeFromDocs]
 | |
| 		static public bool GetVisible(HighlighterRenderer renderer)
 | |
| 		{
 | |
| 			return visibleRenderers.Contains(renderer);
 | |
| 		}
 | |
| 
 | |
| 		// 
 | |
| 		static protected void Initialize()
 | |
| 		{
 | |
| 			if (initialized) { return; }
 | |
| 
 | |
| 			// Initialize shaders and materials
 | |
| 			int l = shaderPaths.Length;
 | |
| 			shaders = new Shader[l];
 | |
| 			materials = new Material[l];
 | |
| 			for (int i = 0; i < l; i++)
 | |
| 			{
 | |
| 				Shader shader = Shader.Find(shaderPaths[i]);
 | |
| 				shaders[i] = shader;
 | |
| 				
 | |
| 				Material material = new Material(shader);
 | |
| 				materials[i] = material;
 | |
| 			}
 | |
| 
 | |
| 			initialized = true;
 | |
| 		}
 | |
| 
 | |
| 		// 
 | |
| 		protected virtual RenderTextureDescriptor GetDescriptor()
 | |
| 		{
 | |
| 			RenderTextureDescriptor descriptor;
 | |
| 
 | |
| 			// RTT
 | |
| 			var targetTexture = cam.targetTexture;
 | |
| 			if (targetTexture != null)
 | |
| 			{
 | |
| 				descriptor = targetTexture.descriptor;
 | |
| 			}
 | |
| 			// VR
 | |
| 			else if (XRSettings.enabled)
 | |
| 			{
 | |
| 				descriptor = XRSettings.eyeTextureDesc;
 | |
| 			}
 | |
| 			// Normal
 | |
| 			else 
 | |
| 			{
 | |
| 				descriptor = new RenderTextureDescriptor(cam.pixelWidth, cam.pixelHeight, RenderTextureFormat.ARGB32, 24);
 | |
| 			}
 | |
| 
 | |
| 			// Overrides
 | |
| 			descriptor.colorFormat = RenderTextureFormat.ARGB32;
 | |
| 			descriptor.sRGB = QualitySettings.activeColorSpace == ColorSpace.Linear;
 | |
| 			descriptor.useMipMap = false;
 | |
| 			descriptor.msaaSamples = GetAA(targetTexture);
 | |
| 
 | |
| 			return descriptor;
 | |
| 		}
 | |
| 
 | |
| 		// 
 | |
| 		protected virtual bool Equals(RenderTextureDescriptor x, RenderTextureDescriptor y)
 | |
| 		{
 | |
| 			return x.width == y.width && x.height == y.height && x.msaaSamples == y.msaaSamples;    // TODO compare all fields?
 | |
| 		}
 | |
| 
 | |
| 		// 
 | |
| 		protected virtual int GetAA(RenderTexture targetTexture)
 | |
| 		{
 | |
| 			int aa = 1;
 | |
| 			switch (_antiAliasing)
 | |
| 			{
 | |
| 				case AntiAliasing.QualitySettings:
 | |
| 					// Set aa value to 1 in case camera is in DeferredLighting or DeferredShading Rendering Path
 | |
| 					if (cam.actualRenderingPath == RenderingPath.DeferredLighting || cam.actualRenderingPath == RenderingPath.DeferredShading)
 | |
| 					{
 | |
| 						aa = 1;
 | |
| 					}
 | |
| 					else
 | |
| 					{
 | |
| 						if (targetTexture == null)
 | |
| 						{
 | |
| 							aa = QualitySettings.antiAliasing;
 | |
| 							if (aa == 0) { aa = 1; }
 | |
| 						}
 | |
| 						else
 | |
| 						{
 | |
| 							aa = targetTexture.antiAliasing;
 | |
| 						}
 | |
| 					}
 | |
| 					break;
 | |
| 				case AntiAliasing.Disabled:
 | |
| 					aa = 1;
 | |
| 					break;
 | |
| 				case AntiAliasing.MSAA2x:
 | |
| 					aa = 2;
 | |
| 					break;
 | |
| 				case AntiAliasing.MSAA4x:
 | |
| 					aa = 4;
 | |
| 					break;
 | |
| 				case AntiAliasing.MSAA8x:
 | |
| 					aa = 8;
 | |
| 					break;
 | |
| 			}
 | |
| 			return aa;
 | |
| 		}
 | |
| 
 | |
| 		// 
 | |
| 		protected virtual bool CheckSupported(bool verbose)
 | |
| 		{
 | |
| 			bool supported = true;
 | |
| 
 | |
| 			// Image Effects supported?
 | |
| 			if (!SystemInfo.supportsImageEffects)
 | |
| 			{
 | |
| 				if (verbose) { Debug.LogError("HighlightingSystem : Image effects is not supported on this platform!"); }
 | |
| 				supported = false;
 | |
| 			}
 | |
| 			
 | |
| 			// Required Render Texture Format supported?
 | |
| 			if (!SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGB32))
 | |
| 			{
 | |
| 				if (verbose) { Debug.LogError("HighlightingSystem : RenderTextureFormat.ARGB32 is not supported on this platform!"); }
 | |
| 				supported = false;
 | |
| 			}
 | |
| 
 | |
| 			// HighlightingOpaque shader supported?
 | |
| 			if (!HighlighterCore.opaqueShader.isSupported)
 | |
| 			{
 | |
| 				if (verbose) { Debug.LogError("HighlightingSystem : HighlightingOpaque shader is not supported on this platform!"); }
 | |
| 				supported = false;
 | |
| 			}
 | |
| 			
 | |
| 			// HighlightingTransparent shader supported?
 | |
| 			if (!HighlighterCore.transparentShader.isSupported)
 | |
| 			{
 | |
| 				if (verbose) { Debug.LogError("HighlightingSystem : HighlightingTransparent shader is not supported on this platform!"); }
 | |
| 				supported = false;
 | |
| 			}
 | |
| 
 | |
| 			// Highlighting shaders supported?
 | |
| 			for (int i = 0; i < shaders.Length; i++)
 | |
| 			{
 | |
| 				Shader shader = shaders[i];
 | |
| 				if (!shader.isSupported)
 | |
| 				{
 | |
| 					if (verbose) { Debug.LogError("HighlightingSystem : Shader '" + shader.name + "' is not supported on this platform!"); }
 | |
| 					supported = false;
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			return supported;
 | |
| 		}
 | |
| 
 | |
| 		// 
 | |
| 		protected virtual void RebuildCommandBuffer()
 | |
| 		{
 | |
| 			renderBuffer.Clear();
 | |
| 
 | |
| 			renderBuffer.BeginSample(profileHighlightingSystem);
 | |
| 
 | |
| 			// Prepare and clear render target
 | |
| 			renderBuffer.SetRenderTarget(highlightingBufferID);
 | |
| 			renderBuffer.ClearRenderTarget(true, true, colorClear);
 | |
| 
 | |
| 			// Fill buffer with highlighters rendering commands
 | |
| 			HighlighterCore.FillBuffer(renderBuffer);
 | |
| 
 | |
| 			RenderTextureDescriptor desc = cachedDescriptor;
 | |
| 			desc.width = highlightingBuffer.width / _downsampleFactor;
 | |
| 			desc.height = highlightingBuffer.height / _downsampleFactor;
 | |
| 			desc.depthBufferBits = 0;
 | |
| 
 | |
| 			// Create two buffers for blurring the image
 | |
| 			renderBuffer.GetTemporaryRT(ShaderPropertyID._HighlightingBlur1, desc, FilterMode.Bilinear);
 | |
| 			renderBuffer.GetTemporaryRT(ShaderPropertyID._HighlightingBlur2, desc, FilterMode.Bilinear);
 | |
| 
 | |
| 			renderBuffer.Blit(highlightingBufferID, blur1ID);
 | |
| 
 | |
| 			// Blur the small texture
 | |
| 			bool oddEven = true;
 | |
| 			for (int i = 0; i < _iterations; i++)
 | |
| 			{
 | |
| 				float off = _blurMinSpread + _blurSpread * i;
 | |
| 				renderBuffer.SetGlobalFloat(ShaderPropertyID._HighlightingBlurOffset, off);
 | |
| 				
 | |
| 				if (oddEven)
 | |
| 				{
 | |
| 					renderBuffer.Blit(blur1ID, blur2ID, blurMaterial);
 | |
| 				}
 | |
| 				else
 | |
| 				{
 | |
| 					renderBuffer.Blit(blur2ID, blur1ID, blurMaterial);
 | |
| 				}
 | |
| 				
 | |
| 				oddEven = !oddEven;
 | |
| 			}
 | |
| 
 | |
| 			// Upscale blurred texture and cut stencil from it
 | |
| 			renderBuffer.Blit(oddEven ? blur1ID : blur2ID, highlightingBufferID, cutMaterial);
 | |
| 
 | |
| 			// Cleanup
 | |
| 			renderBuffer.ReleaseTemporaryRT(ShaderPropertyID._HighlightingBlur1);
 | |
| 			renderBuffer.ReleaseTemporaryRT(ShaderPropertyID._HighlightingBlur2);
 | |
| 
 | |
| 			renderBuffer.EndSample(profileHighlightingSystem);
 | |
| 		}
 | |
| 
 | |
| 		// Blit highlighting result to the destination RenderTexture
 | |
| 		public virtual void Blit(RenderTexture src, RenderTexture dst)
 | |
| 		{
 | |
| 			Graphics.Blit(src, dst, compMaterial);
 | |
| 		}
 | |
| 		#endregion
 | |
| 	}
 | |
| } |