using UnityEngine; using UnityEngine.Rendering; [ExecuteInEditMode] public class CommandBufferBlurRefraction : MonoBehaviour { [SerializeField] private Camera cameraMain; [SerializeField] private Shader blurShader; private Material _material = null; private CommandBuffer _commandBuffer = null; private void Cleanup() { if (!_material) { cameraMain.RemoveCommandBuffer(CameraEvent.AfterSkybox, _commandBuffer); DestroyImmediate(_material); _material = null; } } public void OnDisable() { Cleanup(); } private readonly int screenCopyID = Shader.PropertyToID("_ScreenCopyTexture"); private readonly int blurredID = Shader.PropertyToID("_Temp1"); private readonly int blurredID2 = Shader.PropertyToID("_Temp2"); public void OnEnable() { if (!cameraMain) cameraMain = Camera.main; if (cameraMain == null) return; _material ??= new Material(blurShader) {hideFlags = HideFlags.HideAndDontSave}; _commandBuffer ??= new CommandBuffer() {name = "Grab screen and blur"}; // copy screen into temporary RT _commandBuffer.GetTemporaryRT(screenCopyID, -1, -1, 0, FilterMode.Bilinear); _commandBuffer.Blit(BuiltinRenderTextureType.CurrentActive, screenCopyID); // get two smaller RTs _commandBuffer.GetTemporaryRT(blurredID, -2, -2, 0, FilterMode.Bilinear); _commandBuffer.GetTemporaryRT(blurredID2, -2, -2, 0, FilterMode.Bilinear); // downsample screen copy into smaller RT, release screen RT _commandBuffer.Blit(screenCopyID, blurredID); _commandBuffer.ReleaseTemporaryRT(screenCopyID); // horizontal blur _commandBuffer.SetGlobalVector("offsets", new Vector4(2.0f / Screen.width, 0, 0, 0)); _commandBuffer.Blit(blurredID, blurredID2, _material); // vertical blur _commandBuffer.SetGlobalVector("offsets", new Vector4(0, 2.0f / Screen.height, 0, 0)); _commandBuffer.Blit(blurredID2, blurredID, _material); // horizontal blur _commandBuffer.SetGlobalVector("offsets", new Vector4(4.0f / Screen.width, 0, 0, 0)); _commandBuffer.Blit(blurredID, blurredID2, _material); // vertical blur _commandBuffer.SetGlobalVector("offsets", new Vector4(0, 4.0f / Screen.height, 0, 0)); _commandBuffer.Blit(blurredID2, blurredID, _material); _commandBuffer.SetGlobalTexture("_GrabBlurTexture", blurredID); cameraMain.AddCommandBuffer(CameraEvent.AfterSkybox, _commandBuffer); } }