|  |  |  |  | using UnityEngine; | 
					
						
							|  |  |  |  | using UnityEngine.Rendering; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | [ExecuteInEditMode] | 
					
						
							|  |  |  |  | [ImageEffectAllowedInSceneView] | 
					
						
							|  |  |  |  | [RequireComponent(typeof(Camera))] | 
					
						
							|  |  |  |  | public class CommandBufferBlur : MonoBehaviour | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     Shader _shader; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     Material _material = null; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     Camera _camera = null; | 
					
						
							|  |  |  |  |     CommandBuffer _commandBuffer = null; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     Vector2 _screenResolution = Vector2.zero; | 
					
						
							|  |  |  |  |     RenderTextureFormat _textureFormat = RenderTextureFormat.ARGB32; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     public void Cleanup() | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         if (!Initialized) | 
					
						
							|  |  |  |  |             return; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         _camera.RemoveCommandBuffer(CameraEvent.BeforeForwardAlpha, _commandBuffer); | 
					
						
							|  |  |  |  |         _commandBuffer = null; | 
					
						
							|  |  |  |  |         Object.DestroyImmediate(_material); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     public void OnEnable() | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         Cleanup(); | 
					
						
							|  |  |  |  |         Initialize(); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     public void OnDisable() | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         Cleanup(); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     public bool Initialized | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         get { return _commandBuffer != null; } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     void Initialize() | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         if (Initialized) | 
					
						
							|  |  |  |  |             return; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         if (!_shader) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             _shader = Shader.Find("Hidden/SeparableGlassBlur"); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             if (!_shader) | 
					
						
							|  |  |  |  |                 throw new MissingReferenceException("Unable to find required shader \"Hidden/SeparableGlassBlur\""); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         if (!_material) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             _material = new Material(_shader); | 
					
						
							|  |  |  |  |             _material.hideFlags = HideFlags.HideAndDontSave; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         _camera = GetComponent<Camera>(); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         if (_camera.allowHDR && SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.DefaultHDR)) | 
					
						
							|  |  |  |  |             _textureFormat = RenderTextureFormat.DefaultHDR; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         _commandBuffer = new CommandBuffer(); | 
					
						
							|  |  |  |  |         _commandBuffer.name = "Blur screen"; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         int numIterations = 4; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         Vector2[] sizes = { | 
					
						
							|  |  |  |  |             new Vector2(Screen.width, Screen.height), | 
					
						
							|  |  |  |  |             new Vector2(Screen.width / 2, Screen.height / 2), | 
					
						
							|  |  |  |  |             new Vector2(Screen.width / 4, Screen.height / 4), | 
					
						
							|  |  |  |  |             new Vector2(Screen.width / 8, Screen.height / 8), | 
					
						
							|  |  |  |  |         }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         for (int i = 0; i < numIterations; ++i) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             int screenCopyID = Shader.PropertyToID("_ScreenCopyTexture"); | 
					
						
							|  |  |  |  |             _commandBuffer.GetTemporaryRT(screenCopyID, -1, -1, 0, FilterMode.Bilinear, _textureFormat); | 
					
						
							|  |  |  |  |             _commandBuffer.Blit(BuiltinRenderTextureType.CurrentActive, screenCopyID); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             int blurredID = Shader.PropertyToID("_Grab" + i + "_Temp1"); | 
					
						
							|  |  |  |  |             int blurredID2 = Shader.PropertyToID("_Grab" + i + "_Temp2"); | 
					
						
							|  |  |  |  |             _commandBuffer.GetTemporaryRT(blurredID, (int)sizes[i].x, (int)sizes[i].y, 0, FilterMode.Bilinear, _textureFormat); | 
					
						
							|  |  |  |  |             _commandBuffer.GetTemporaryRT(blurredID2, (int)sizes[i].x, (int)sizes[i].y, 0, FilterMode.Bilinear, _textureFormat); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             _commandBuffer.Blit(screenCopyID, blurredID); | 
					
						
							|  |  |  |  |             _commandBuffer.ReleaseTemporaryRT(screenCopyID); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             _commandBuffer.SetGlobalVector("offsets", new Vector4(2.0f / sizes[i].x, 0, 0, 0)); | 
					
						
							|  |  |  |  |             _commandBuffer.Blit(blurredID, blurredID2, _material); | 
					
						
							|  |  |  |  |             _commandBuffer.SetGlobalVector("offsets", new Vector4(0, 2.0f / sizes[i].y, 0, 0)); | 
					
						
							|  |  |  |  |             _commandBuffer.Blit(blurredID2, blurredID, _material); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             _commandBuffer.SetGlobalTexture("_GrabBlurTexture_" + i, blurredID); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         _camera.AddCommandBuffer(CameraEvent.BeforeForwardAlpha, _commandBuffer); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         _screenResolution = new Vector2(Screen.width, Screen.height); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     void OnPreRender() | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  |         if (_screenResolution != new Vector2(Screen.width, Screen.height)) | 
					
						
							|  |  |  |  |             Cleanup(); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         Initialize(); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | } |