BlurEffect.cs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. using UnityEngine;
  2. using System.Collections;
  3. [ExecuteInEditMode]
  4. [AddComponentMenu("Image Effects/Blur")]
  5. public class BlurEffect : MonoBehaviour
  6. {
  7. /// Blur iterations - larger number means more blur.
  8. public int iterations = 3;
  9. /// Blur spread for each iteration. Lower values
  10. /// give better looking blur, but require more iterations to
  11. /// get large blurs. Value is usually between 0.5 and 1.0.
  12. public float blurSpread = 0.6f;
  13. // --------------------------------------------------------
  14. // The blur iteration shader.
  15. // Basically it just takes 4 texture samples and averages them.
  16. // By applying it repeatedly and spreading out sample locations
  17. // we get a Gaussian blur approximation.
  18. private static string blurMatString =
  19. @"Shader ""BlurConeTap"" {
  20. Properties { _MainTex ("""", any) = """" {} }
  21. SubShader {
  22. Pass {
  23. ZTest Always Cull Off ZWrite Off Fog { Mode Off }
  24. SetTexture [_MainTex] {constantColor (0,0,0,0.25) combine texture * constant alpha}
  25. SetTexture [_MainTex] {constantColor (0,0,0,0.25) combine texture * constant + previous}
  26. SetTexture [_MainTex] {constantColor (0,0,0,0.25) combine texture * constant + previous}
  27. SetTexture [_MainTex] {constantColor (0,0,0,0.25) combine texture * constant + previous}
  28. }
  29. }
  30. Fallback off
  31. }";
  32. static Material m_Material = null;
  33. protected static Material material {
  34. get {
  35. if (m_Material == null) {
  36. m_Material = new Material( blurMatString );
  37. m_Material.hideFlags = HideFlags.HideAndDontSave;
  38. m_Material.shader.hideFlags = HideFlags.HideAndDontSave;
  39. }
  40. return m_Material;
  41. }
  42. }
  43. protected void OnDisable() {
  44. if( m_Material ) {
  45. DestroyImmediate( m_Material.shader );
  46. DestroyImmediate( m_Material );
  47. }
  48. }
  49. // --------------------------------------------------------
  50. protected void Start()
  51. {
  52. // Disable if we don't support image effects
  53. if (!SystemInfo.supportsImageEffects) {
  54. enabled = false;
  55. return;
  56. }
  57. // Disable if the shader can't run on the users graphics card
  58. if (!material.shader.isSupported) {
  59. enabled = false;
  60. return;
  61. }
  62. }
  63. // Performs one blur iteration.
  64. public void FourTapCone (RenderTexture source, RenderTexture dest, int iteration)
  65. {
  66. float off = 0.5f + iteration*blurSpread;
  67. Graphics.BlitMultiTap (source, dest, material,
  68. new Vector2(-off, -off),
  69. new Vector2(-off, off),
  70. new Vector2( off, off),
  71. new Vector2( off, -off)
  72. );
  73. }
  74. // Downsamples the texture to a quarter resolution.
  75. private void DownSample4x (RenderTexture source, RenderTexture dest)
  76. {
  77. float off = 1.0f;
  78. Graphics.BlitMultiTap (source, dest, material,
  79. new Vector2(-off, -off),
  80. new Vector2(-off, off),
  81. new Vector2( off, off),
  82. new Vector2( off, -off)
  83. );
  84. }
  85. // Called by the camera to apply the image effect
  86. void OnRenderImage (RenderTexture source, RenderTexture destination) {
  87. RenderTexture buffer = RenderTexture.GetTemporary(source.width/4, source.height/4, 0);
  88. RenderTexture buffer2 = RenderTexture.GetTemporary(source.width/4, source.height/4, 0);
  89. // Copy source to the 4x4 smaller texture.
  90. DownSample4x (source, buffer);
  91. // Blur the small texture
  92. bool oddEven = true;
  93. for(int i = 0; i < iterations; i++)
  94. {
  95. if( oddEven )
  96. FourTapCone (buffer, buffer2, i);
  97. else
  98. FourTapCone (buffer2, buffer, i);
  99. oddEven = !oddEven;
  100. }
  101. if( oddEven )
  102. Graphics.Blit(buffer, destination);
  103. else
  104. Graphics.Blit(buffer2, destination);
  105. RenderTexture.ReleaseTemporary(buffer);
  106. RenderTexture.ReleaseTemporary(buffer2);
  107. }
  108. }