CommandBufferBlurRefraction.cs 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. using UnityEngine;
  2. using UnityEngine.Rendering;
  3. [ExecuteInEditMode]
  4. public class CommandBufferBlurRefraction : MonoBehaviour
  5. {
  6. [SerializeField] private Camera cameraMain;
  7. [SerializeField] private Shader blurShader;
  8. private Material _material = null;
  9. private CommandBuffer _commandBuffer = null;
  10. private void Cleanup()
  11. {
  12. if (!_material)
  13. {
  14. cameraMain.RemoveCommandBuffer(CameraEvent.AfterSkybox, _commandBuffer);
  15. DestroyImmediate(_material);
  16. _material = null;
  17. }
  18. }
  19. public void OnDisable()
  20. {
  21. Cleanup();
  22. }
  23. private readonly int screenCopyID = Shader.PropertyToID("_ScreenCopyTexture");
  24. private readonly int blurredID = Shader.PropertyToID("_Temp1");
  25. private readonly int blurredID2 = Shader.PropertyToID("_Temp2");
  26. public void OnEnable()
  27. {
  28. if (!cameraMain)
  29. cameraMain = Camera.main;
  30. if (cameraMain == null)
  31. return;
  32. _material ??= new Material(blurShader) {hideFlags = HideFlags.HideAndDontSave};
  33. _commandBuffer ??= new CommandBuffer() {name = "Grab screen and blur"};
  34. // copy screen into temporary RT
  35. _commandBuffer.GetTemporaryRT(screenCopyID, -1, -1, 0, FilterMode.Bilinear);
  36. _commandBuffer.Blit(BuiltinRenderTextureType.CurrentActive, screenCopyID);
  37. // get two smaller RTs
  38. _commandBuffer.GetTemporaryRT(blurredID, -2, -2, 0, FilterMode.Bilinear);
  39. _commandBuffer.GetTemporaryRT(blurredID2, -2, -2, 0, FilterMode.Bilinear);
  40. // downsample screen copy into smaller RT, release screen RT
  41. _commandBuffer.Blit(screenCopyID, blurredID);
  42. _commandBuffer.ReleaseTemporaryRT(screenCopyID);
  43. // horizontal blur
  44. _commandBuffer.SetGlobalVector("offsets", new Vector4(2.0f / Screen.width, 0, 0, 0));
  45. _commandBuffer.Blit(blurredID, blurredID2, _material);
  46. // vertical blur
  47. _commandBuffer.SetGlobalVector("offsets", new Vector4(0, 2.0f / Screen.height, 0, 0));
  48. _commandBuffer.Blit(blurredID2, blurredID, _material);
  49. // horizontal blur
  50. _commandBuffer.SetGlobalVector("offsets", new Vector4(4.0f / Screen.width, 0, 0, 0));
  51. _commandBuffer.Blit(blurredID, blurredID2, _material);
  52. // vertical blur
  53. _commandBuffer.SetGlobalVector("offsets", new Vector4(0, 4.0f / Screen.height, 0, 0));
  54. _commandBuffer.Blit(blurredID2, blurredID, _material);
  55. _commandBuffer.SetGlobalTexture("_GrabBlurTexture", blurredID);
  56. cameraMain.AddCommandBuffer(CameraEvent.AfterSkybox, _commandBuffer);
  57. }
  58. }