UIBlur_Shared.cginc 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. static const float MAX_RADIUS = 64;
  2. static const float ITER_STEP = 2;
  3. #include "UnityCG.cginc"
  4. #include "UnityUI.cginc"
  5. struct appdata_t
  6. {
  7. float4 vertex : POSITION;
  8. float2 texcoord: TEXCOORD0;
  9. float4 color : COLOR;
  10. };
  11. struct v2f
  12. {
  13. float4 vertex : POSITION;
  14. float4 uvgrab : TEXCOORD0;
  15. float4 worldpos : TEXCOORD1;
  16. float2 uvmain : TEXCOORD2;
  17. float4 color : COLOR;
  18. };
  19. sampler2D _MainTex;
  20. float4 _MainTex_ST;
  21. v2f vert(appdata_t v)
  22. {
  23. v2f OUT;
  24. UNITY_SETUP_INSTANCE_ID(v);
  25. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
  26. OUT.worldpos = v.vertex;
  27. OUT.vertex = UnityObjectToClipPos(v.vertex);
  28. #if UNITY_UV_STARTS_AT_TOP
  29. float scale = -1.0;
  30. #else
  31. float scale = 1.0;
  32. #endif
  33. OUT.uvgrab.xy = (float2(OUT.vertex.x, OUT.vertex.y*scale) + OUT.vertex.w) * 0.5;
  34. OUT.uvgrab.zw = OUT.vertex.zw;
  35. OUT.uvmain = TRANSFORM_TEX(v.texcoord, _MainTex);
  36. OUT.color = v.color;
  37. return OUT;
  38. }
  39. float4 _OverlayColor;
  40. float _Radius;
  41. float4 _ClipRect;
  42. half4 layerBlend(half4 back, half4 front)
  43. {
  44. half a0 = front.a;
  45. half a1 = back.a;
  46. half a01 = (1 - a0)*a1 + a0;
  47. return half4(
  48. ((1 - a0)*a1*back.r + a0*front.r) / a01,
  49. ((1 - a0)*a1*back.g + a0*front.g) / a01,
  50. ((1 - a0)*a1*back.b + a0*front.b) / a01,
  51. a01);
  52. }
  53. // Like Photoshop, see http://www.deepskycolors.com/archive/2010/04/21/formulas-for-Photoshop-blending-modes.html
  54. #define BLEND_OVERLAY(a, b) b <= 0.5 ? (2*b)*a : (1 - (1-2*(b-0.5)) * (1-a))
  55. half3 overlayBlend(half3 back, half3 front)
  56. {
  57. return
  58. half3(
  59. BLEND_OVERLAY(back.r, front.r),
  60. BLEND_OVERLAY(back.g, front.g),
  61. BLEND_OVERLAY(back.b, front.b)
  62. );
  63. }
  64. half4 GrabPixel(sampler2D tex, float4 uv)
  65. {
  66. half4 pixel = tex2Dproj(tex, UNITY_PROJ_COORD(uv));
  67. return half4(pixel.rgb, 1);
  68. }
  69. half4 GrabPixelXY(sampler2D tex, float4 uv, float4 size, half kernelx, half kernely)
  70. {
  71. half4 pixel = tex2Dproj(
  72. tex,
  73. UNITY_PROJ_COORD(
  74. float4(
  75. uv.x + size.x * kernelx,
  76. uv.y + size.y * kernely,
  77. uv.z,
  78. uv.w)
  79. )
  80. );
  81. return half4(pixel.rgb, 1);
  82. }
  83. half4 GetBlurInDir(v2f IN, half4 pixel, sampler2D tex, float4 size, half dirx, half diry)
  84. {
  85. #ifdef UNITY_COLORSPACE_GAMMA
  86. float4 color = _OverlayColor;
  87. #else
  88. float4 color = float4(LinearToGammaSpace(_OverlayColor.rgb), _OverlayColor.a);
  89. #endif
  90. #if IS_BLUR_ALPHA_MASKED
  91. float visibility = color.a*pixel.a;
  92. #else
  93. float visibility = color.a;
  94. #endif
  95. float radius = clamp(_Radius, 0, MAX_RADIUS);
  96. visibility *= UnityGet2DClipping(IN.worldpos.xy, _ClipRect);
  97. float4 sum = GrabPixel(tex, IN.uvgrab);
  98. half steps = 1;
  99. for (half range = ITER_STEP; range <= radius; range += ITER_STEP)
  100. {
  101. sum += GrabPixelXY(tex, IN.uvgrab, size, range*dirx, range*diry);
  102. sum += GrabPixelXY(tex, IN.uvgrab, size, -range*dirx, -range*diry);
  103. steps += 2;
  104. }
  105. half4 result = sum/steps;
  106. return half4(overlayBlend(result.rgb, color.rgb), result.a*visibility);
  107. }