UIEffect.cginc 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. #ifndef UI_EFFECT_INCLUDED
  2. #define UI_EFFECT_INCLUDED
  3. sampler2D _TransitionTex;
  4. sampler2D _ParamTex;
  5. #if GRAYSCALE | SEPIA | NEGA | PIXEL | MONO | CUTOFF | HUE
  6. #define UI_TONE
  7. #endif
  8. #if ADD | SUBTRACT | FILL
  9. #define UI_COLOR
  10. #endif
  11. #if FASTBLUR | MEDIUMBLUR | DETAILBLUR
  12. #define UI_BLUR
  13. #endif
  14. // Unpack float to low-precision [0-1] fixed4.
  15. fixed4 UnpackToVec4(float value)
  16. {
  17. const int PACKER_STEP = 64;
  18. const int PRECISION = PACKER_STEP - 1;
  19. fixed4 unpacked;
  20. unpacked.x = (value % PACKER_STEP) / PRECISION;
  21. value = floor(value / PACKER_STEP);
  22. unpacked.y = (value % PACKER_STEP) / PRECISION;
  23. value = floor(value / PACKER_STEP);
  24. unpacked.z = (value % PACKER_STEP) / PRECISION;
  25. value = floor(value / PACKER_STEP);
  26. unpacked.w = (value % PACKER_STEP) / PRECISION;
  27. return unpacked;
  28. }
  29. // Unpack float to low-precision [0-1] fixed3.
  30. fixed3 UnpackToVec3(float value)
  31. {
  32. const int PACKER_STEP = 256;
  33. const int PRECISION = PACKER_STEP - 1;
  34. fixed3 unpacked;
  35. unpacked.x = (value % (PACKER_STEP)) / (PACKER_STEP - 1);
  36. value = floor(value / (PACKER_STEP));
  37. unpacked.y = (value % PACKER_STEP) / (PACKER_STEP - 1);
  38. value = floor(value / PACKER_STEP);
  39. unpacked.z = (value % PACKER_STEP) / (PACKER_STEP - 1);
  40. return unpacked;
  41. }
  42. // Unpack float to low-precision [0-1] half2.
  43. half2 UnpackToVec2(float value)
  44. {
  45. const int PACKER_STEP = 4096;
  46. const int PRECISION = PACKER_STEP - 1;
  47. half2 unpacked;
  48. unpacked.x = (value % (PACKER_STEP)) / (PACKER_STEP - 1);
  49. value = floor(value / (PACKER_STEP));
  50. unpacked.y = (value % PACKER_STEP) / (PACKER_STEP - 1);
  51. return unpacked;
  52. }
  53. // Sample texture with blurring.
  54. // * Fast: Sample texture with 3x3 kernel.
  55. // * Medium: Sample texture with 5x5 kernel.
  56. // * Detail: Sample texture with 7x7 kernel.
  57. fixed4 Tex2DBlurring (sampler2D tex, half2 texcood, half2 blur, half4 mask)
  58. {
  59. #if FASTBLUR && EX
  60. const int KERNEL_SIZE = 5;
  61. const float KERNEL_[5] = { 0.2486, 0.7046, 1.0, 0.7046, 0.2486};
  62. #elif MEDIUMBLUR && EX
  63. const int KERNEL_SIZE = 9;
  64. const float KERNEL_[9] = { 0.0438, 0.1719, 0.4566, 0.8204, 1.0, 0.8204, 0.4566, 0.1719, 0.0438};
  65. #elif DETAILBLUR && EX
  66. const int KERNEL_SIZE = 13;
  67. const float KERNEL_[13] = { 0.0438, 0.1138, 0.2486, 0.4566, 0.7046, 0.9141, 1.0, 0.9141, 0.7046, 0.4566, 0.2486, 0.1138, 0.0438};
  68. #elif FASTBLUR
  69. const int KERNEL_SIZE = 3;
  70. const float KERNEL_[3] = { 0.4566, 1.0, 0.4566};
  71. #elif MEDIUMBLUR
  72. const int KERNEL_SIZE = 5;
  73. const float KERNEL_[5] = { 0.2486, 0.7046, 1.0, 0.7046, 0.2486};
  74. #elif DETAILBLUR
  75. const int KERNEL_SIZE = 7;
  76. const float KERNEL_[7] = { 0.1719, 0.4566, 0.8204, 1.0, 0.8204, 0.4566, 0.1719};
  77. #else
  78. const int KERNEL_SIZE = 1;
  79. const float KERNEL_[1] = { 1.0 };
  80. #endif
  81. float4 o = 0;
  82. float sum = 0;
  83. float2 shift = 0;
  84. for(int x = 0; x < KERNEL_SIZE; x++)
  85. {
  86. shift.x = blur.x * (float(x) - KERNEL_SIZE/2);
  87. for(int y = 0; y < KERNEL_SIZE; y++)
  88. {
  89. shift.y = blur.y * (float(y) - KERNEL_SIZE/2);
  90. float2 uv = texcood + shift;
  91. float weight = KERNEL_[x] * KERNEL_[y];
  92. sum += weight;
  93. #if EX
  94. fixed masked = min(mask.x <= uv.x, uv.x <= mask.z) * min(mask.y <= uv.y, uv.y <= mask.w);
  95. o += lerp(fixed4(0.5, 0.5, 0.5, 0), tex2D(tex, uv), masked) * weight;
  96. #else
  97. o += tex2D(tex, uv) * weight;
  98. #endif
  99. }
  100. }
  101. return o / sum;
  102. }
  103. // Sample texture with blurring.
  104. // * Fast: Sample texture with 3x3 kernel.
  105. // * Medium: Sample texture with 5x5 kernel.
  106. // * Detail: Sample texture with 7x7 kernel.
  107. fixed4 Tex2DBlurring (sampler2D tex, half2 texcood, half2 blur)
  108. {
  109. return Tex2DBlurring(tex, texcood, blur, half4(0,0,1,1));
  110. }
  111. // Sample texture with blurring.
  112. // * Fast: Sample texture with 3x1 kernel.
  113. // * Medium: Sample texture with 5x1 kernel.
  114. // * Detail: Sample texture with 7x1 kernel.
  115. fixed4 Tex2DBlurring1D (sampler2D tex, half2 uv, half2 blur)
  116. {
  117. #if FASTBLUR
  118. const int KERNEL_SIZE = 3;
  119. #elif MEDIUMBLUR
  120. const int KERNEL_SIZE = 5;
  121. #elif DETAILBLUR
  122. const int KERNEL_SIZE = 7;
  123. #else
  124. const int KERNEL_SIZE = 1;
  125. #endif
  126. float4 o = 0;
  127. float sum = 0;
  128. float weight;
  129. half2 texcood;
  130. for(int i = -KERNEL_SIZE/2; i <= KERNEL_SIZE/2; i++)
  131. {
  132. texcood = uv;
  133. texcood.x += blur.x * i;
  134. texcood.y += blur.y * i;
  135. weight = 1.0/(abs(i)+2);
  136. o += tex2D(tex, texcood)*weight;
  137. sum += weight;
  138. }
  139. return o / sum;
  140. }
  141. fixed3 shift_hue(fixed3 RGB, half VSU, half VSW)
  142. {
  143. fixed3 result;
  144. result.x = (0.299 + 0.701*VSU + 0.168*VSW)*RGB.x
  145. + (0.587 - 0.587*VSU + 0.330*VSW)*RGB.y
  146. + (0.114 - 0.114*VSU - 0.497*VSW)*RGB.z;
  147. result.y = (0.299 - 0.299*VSU - 0.328*VSW)*RGB.x
  148. + (0.587 + 0.413*VSU + 0.035*VSW)*RGB.y
  149. + (0.114 - 0.114*VSU + 0.292*VSW)*RGB.z;
  150. result.z = (0.299 - 0.3*VSU + 1.25*VSW)*RGB.x
  151. + (0.587 - 0.588*VSU - 1.05*VSW)*RGB.y
  152. + (0.114 + 0.886*VSU - 0.203*VSW)*RGB.z;
  153. return result;
  154. }
  155. // Apply tone effect.
  156. fixed4 ApplyToneEffect(fixed4 color, fixed factor)
  157. {
  158. #ifdef GRAYSCALE
  159. color.rgb = lerp(color.rgb, Luminance(color.rgb), factor);
  160. #elif SEPIA
  161. color.rgb = lerp(color.rgb, Luminance(color.rgb) * half3(1.07, 0.74, 0.43), factor);
  162. #elif NEGA
  163. color.rgb = lerp(color.rgb, 1 - color.rgb, factor);
  164. #endif
  165. return color;
  166. }
  167. // Apply color effect.
  168. fixed4 ApplyColorEffect(half4 color, half4 factor)
  169. {
  170. #if FILL
  171. color.rgb = lerp(color.rgb, factor.rgb, factor.a);
  172. #elif ADD
  173. color.rgb += factor.rgb * factor.a;
  174. #elif SUBTRACT
  175. color.rgb -= factor.rgb * factor.a;
  176. #else
  177. color.rgb = lerp(color.rgb, color.rgb * factor.rgb, factor.a);
  178. #endif
  179. #if CUTOFF
  180. color.a = factor.a;
  181. #endif
  182. return color;
  183. }
  184. // Apply transition effect.
  185. fixed4 ApplyTransitionEffect(half4 color, half3 transParam)
  186. {
  187. fixed4 param = tex2D(_ParamTex, float2(0.25, transParam.z));
  188. float alpha = tex2D(_TransitionTex, transParam.xy).a;
  189. #if REVERSE
  190. fixed effectFactor = 1 - param.x;
  191. #else
  192. fixed effectFactor = param.x;
  193. #endif
  194. #if FADE
  195. color.a *= saturate(alpha + (1 - effectFactor * 2));
  196. #elif CUTOFF
  197. color.a *= step(0.001, color.a * alpha - effectFactor);
  198. #elif DISSOLVE
  199. fixed width = param.y/4;
  200. fixed softness = param.z;
  201. fixed3 dissolveColor = tex2D(_ParamTex, float2(0.75, transParam.z)).rgb;
  202. float factor = alpha - effectFactor * ( 1 + width ) + width;
  203. fixed edgeLerp = step(factor, color.a) * saturate((width - factor)*16/ softness);
  204. color = ApplyColorEffect(color, fixed4(dissolveColor, edgeLerp));
  205. color.a *= saturate((factor)*32/ softness);
  206. #endif
  207. return color;
  208. }
  209. // Apply shiny effect.
  210. half4 ApplyShinyEffect(half4 color, half2 shinyParam)
  211. {
  212. fixed nomalizedPos = shinyParam.x;
  213. fixed4 param1 = tex2D(_ParamTex, float2(0.25, shinyParam.y));
  214. fixed4 param2 = tex2D(_ParamTex, float2(0.75, shinyParam.y));
  215. half location = param1.x * 2 - 0.5;
  216. fixed width = param1.y;
  217. fixed soft = param1.z;
  218. fixed brightness = param1.w;
  219. fixed gloss = param2.x;
  220. half normalized = 1 - saturate(abs((nomalizedPos - location) / width));
  221. half shinePower = smoothstep(0, soft, normalized);
  222. half3 reflectColor = lerp(fixed3(1,1,1), color.rgb * 7, gloss);
  223. color.rgb += color.a * (shinePower / 2) * brightness * reflectColor;
  224. return color;
  225. }
  226. half3 RgbToHsv(half3 c) {
  227. half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
  228. half4 p = lerp(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g));
  229. half4 q = lerp(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r));
  230. half d = q.x - min(q.w, q.y);
  231. half e = 1.0e-10;
  232. return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
  233. }
  234. half3 HsvToRgb(half3 c) {
  235. c = half3(c.x, clamp(c.yz, 0.0, 1.0));
  236. half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
  237. half3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);
  238. return c.z * lerp(K.xxx, clamp(p.xyz - K.xxx, 0.0, 1.0), c.y);
  239. }
  240. // Apply Hsv effect.
  241. half4 ApplyHsvEffect(half4 color, half param)
  242. {
  243. fixed4 param1 = tex2D(_ParamTex, float2(0.25, param));
  244. fixed4 param2 = tex2D(_ParamTex, float2(0.75, param));
  245. fixed3 targetHsv = param1.rgb;
  246. fixed3 targetRange = param1.w;
  247. fixed3 hsvShift = param2.xyz - 0.5;
  248. half3 hsv = RgbToHsv(color.rgb);
  249. half3 range = abs(hsv - targetHsv);
  250. half diff = max(max(min(1-range.x, range.x), min(1-range.y, range.y)/10), min(1-range.z, range.z)/10);
  251. fixed masked = step(diff, targetRange);
  252. color.rgb = HsvToRgb(hsv + hsvShift * masked);
  253. return color;
  254. }
  255. #endif // UI_EFFECT_INCLUDED