MobileBloom.shader 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
  2. Shader "Hidden/FastBloom" {
  3. Properties {
  4. _MainTex ("Base (RGB)", 2D) = "white" {}
  5. _Bloom ("Bloom (RGB)", 2D) = "black" {}
  6. }
  7. CGINCLUDE
  8. #include "UnityCG.cginc"
  9. sampler2D _MainTex;
  10. sampler2D _Bloom;
  11. uniform half4 _MainTex_TexelSize;
  12. uniform half4 _Parameter;
  13. uniform half4 _OffsetsA;
  14. uniform half4 _OffsetsB;
  15. #define ONE_MINUS_THRESHHOLD_TIMES_INTENSITY _Parameter.w
  16. #define THRESHHOLD _Parameter.z
  17. struct v2f_simple
  18. {
  19. float4 pos : SV_POSITION;
  20. half2 uv : TEXCOORD0;
  21. #if UNITY_UV_STARTS_AT_TOP
  22. half2 uv2 : TEXCOORD1;
  23. #endif
  24. };
  25. v2f_simple vertBloom ( appdata_img v )
  26. {
  27. v2f_simple o;
  28. o.pos = UnityObjectToClipPos (v.vertex);
  29. o.uv = v.texcoord;
  30. #if UNITY_UV_STARTS_AT_TOP
  31. o.uv2 = v.texcoord;
  32. if (_MainTex_TexelSize.y < 0.0)
  33. o.uv.y = 1.0 - o.uv.y;
  34. #endif
  35. return o;
  36. }
  37. struct v2f_tap
  38. {
  39. float4 pos : SV_POSITION;
  40. half2 uv20 : TEXCOORD0;
  41. half2 uv21 : TEXCOORD1;
  42. half2 uv22 : TEXCOORD2;
  43. half2 uv23 : TEXCOORD3;
  44. };
  45. v2f_tap vert4Tap ( appdata_img v )
  46. {
  47. v2f_tap o;
  48. o.pos = UnityObjectToClipPos (v.vertex);
  49. o.uv20 = v.texcoord + _MainTex_TexelSize.xy;
  50. o.uv21 = v.texcoord + _MainTex_TexelSize.xy * half2(-0.5h,-0.5h);
  51. o.uv22 = v.texcoord + _MainTex_TexelSize.xy * half2(0.5h,-0.5h);
  52. o.uv23 = v.texcoord + _MainTex_TexelSize.xy * half2(-0.5h,0.5h);
  53. return o;
  54. }
  55. fixed4 fragBloom ( v2f_simple i ) : SV_Target
  56. {
  57. #if UNITY_UV_STARTS_AT_TOP
  58. fixed4 color = tex2D(_MainTex, i.uv2);
  59. return color + tex2D(_Bloom, i.uv);
  60. #else
  61. fixed4 color = tex2D(_MainTex, i.uv);
  62. return color + tex2D(_Bloom, i.uv);
  63. #endif
  64. }
  65. fixed4 fragDownsample ( v2f_tap i ) : SV_Target
  66. {
  67. fixed4 color = tex2D (_MainTex, i.uv20);
  68. color += tex2D (_MainTex, i.uv21);
  69. color += tex2D (_MainTex, i.uv22);
  70. color += tex2D (_MainTex, i.uv23);
  71. return max(color/4 - THRESHHOLD, 0) * ONE_MINUS_THRESHHOLD_TIMES_INTENSITY;
  72. }
  73. // weight curves
  74. static const half curve[7] = { 0.0205, 0.0855, 0.232, 0.324, 0.232, 0.0855, 0.0205 }; // gauss'ish blur weights
  75. static const half4 curve4[7] = { half4(0.0205,0.0205,0.0205,0), half4(0.0855,0.0855,0.0855,0), half4(0.232,0.232,0.232,0),
  76. half4(0.324,0.324,0.324,1), half4(0.232,0.232,0.232,0), half4(0.0855,0.0855,0.0855,0), half4(0.0205,0.0205,0.0205,0) };
  77. struct v2f_withBlurCoords8
  78. {
  79. float4 pos : SV_POSITION;
  80. half4 uv : TEXCOORD0;
  81. half2 offs : TEXCOORD1;
  82. };
  83. struct v2f_withBlurCoordsSGX
  84. {
  85. float4 pos : SV_POSITION;
  86. half2 uv : TEXCOORD0;
  87. half4 offs[3] : TEXCOORD1;
  88. };
  89. v2f_withBlurCoords8 vertBlurHorizontal (appdata_img v)
  90. {
  91. v2f_withBlurCoords8 o;
  92. o.pos = UnityObjectToClipPos (v.vertex);
  93. o.uv = half4(v.texcoord.xy,1,1);
  94. o.offs = _MainTex_TexelSize.xy * half2(1.0, 0.0) * _Parameter.x;
  95. return o;
  96. }
  97. v2f_withBlurCoords8 vertBlurVertical (appdata_img v)
  98. {
  99. v2f_withBlurCoords8 o;
  100. o.pos = UnityObjectToClipPos (v.vertex);
  101. o.uv = half4(v.texcoord.xy,1,1);
  102. o.offs = _MainTex_TexelSize.xy * half2(0.0, 1.0) * _Parameter.x;
  103. return o;
  104. }
  105. half4 fragBlur8 ( v2f_withBlurCoords8 i ) : SV_Target
  106. {
  107. half2 uv = i.uv.xy;
  108. half2 netFilterWidth = i.offs;
  109. half2 coords = uv - netFilterWidth * 3.0;
  110. half4 color = 0;
  111. for( int l = 0; l < 7; l++ )
  112. {
  113. half4 tap = tex2D(_MainTex, coords);
  114. color += tap * curve4[l];
  115. coords += netFilterWidth;
  116. }
  117. return color;
  118. }
  119. v2f_withBlurCoordsSGX vertBlurHorizontalSGX (appdata_img v)
  120. {
  121. v2f_withBlurCoordsSGX o;
  122. o.pos = UnityObjectToClipPos (v.vertex);
  123. o.uv = v.texcoord.xy;
  124. half2 netFilterWidth = _MainTex_TexelSize.xy * half2(1.0, 0.0) * _Parameter.x;
  125. half4 coords = -netFilterWidth.xyxy * 3.0;
  126. o.offs[0] = v.texcoord.xyxy + coords * half4(1.0h,1.0h,-1.0h,-1.0h);
  127. coords += netFilterWidth.xyxy;
  128. o.offs[1] = v.texcoord.xyxy + coords * half4(1.0h,1.0h,-1.0h,-1.0h);
  129. coords += netFilterWidth.xyxy;
  130. o.offs[2] = v.texcoord.xyxy + coords * half4(1.0h,1.0h,-1.0h,-1.0h);
  131. return o;
  132. }
  133. v2f_withBlurCoordsSGX vertBlurVerticalSGX (appdata_img v)
  134. {
  135. v2f_withBlurCoordsSGX o;
  136. o.pos = UnityObjectToClipPos (v.vertex);
  137. o.uv = half4(v.texcoord.xy,1,1);
  138. half2 netFilterWidth = _MainTex_TexelSize.xy * half2(0.0, 1.0) * _Parameter.x;
  139. half4 coords = -netFilterWidth.xyxy * 3.0;
  140. o.offs[0] = v.texcoord.xyxy + coords * half4(1.0h,1.0h,-1.0h,-1.0h);
  141. coords += netFilterWidth.xyxy;
  142. o.offs[1] = v.texcoord.xyxy + coords * half4(1.0h,1.0h,-1.0h,-1.0h);
  143. coords += netFilterWidth.xyxy;
  144. o.offs[2] = v.texcoord.xyxy + coords * half4(1.0h,1.0h,-1.0h,-1.0h);
  145. return o;
  146. }
  147. half4 fragBlurSGX ( v2f_withBlurCoordsSGX i ) : SV_Target
  148. {
  149. half2 uv = i.uv.xy;
  150. half4 color = tex2D(_MainTex, i.uv) * curve4[3];
  151. for( int l = 0; l < 3; l++ )
  152. {
  153. half4 tapA = tex2D(_MainTex, i.offs[l].xy);
  154. half4 tapB = tex2D(_MainTex, i.offs[l].zw);
  155. color += (tapA + tapB) * curve4[l];
  156. }
  157. return color;
  158. }
  159. ENDCG
  160. SubShader {
  161. ZTest Off Cull Off ZWrite Off Blend Off
  162. // 0
  163. Pass {
  164. CGPROGRAM
  165. #pragma vertex vertBloom
  166. #pragma fragment fragBloom
  167. ENDCG
  168. }
  169. // 1
  170. Pass {
  171. CGPROGRAM
  172. #pragma vertex vert4Tap
  173. #pragma fragment fragDownsample
  174. ENDCG
  175. }
  176. // 2
  177. Pass {
  178. ZTest Always
  179. Cull Off
  180. CGPROGRAM
  181. #pragma vertex vertBlurVertical
  182. #pragma fragment fragBlur8
  183. ENDCG
  184. }
  185. // 3
  186. Pass {
  187. ZTest Always
  188. Cull Off
  189. CGPROGRAM
  190. #pragma vertex vertBlurHorizontal
  191. #pragma fragment fragBlur8
  192. ENDCG
  193. }
  194. // alternate blur
  195. // 4
  196. Pass {
  197. ZTest Always
  198. Cull Off
  199. CGPROGRAM
  200. #pragma vertex vertBlurVerticalSGX
  201. #pragma fragment fragBlurSGX
  202. ENDCG
  203. }
  204. // 5
  205. Pass {
  206. ZTest Always
  207. Cull Off
  208. CGPROGRAM
  209. #pragma vertex vertBlurHorizontalSGX
  210. #pragma fragment fragBlurSGX
  211. ENDCG
  212. }
  213. }
  214. FallBack Off
  215. }