TexturePalette.gdshader 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. shader_type canvas_item;
  2. // 输入参数
  3. uniform int PaletteCount;
  4. uniform vec4 BasicColor[8] : source_color;
  5. uniform vec4 ModulateColor[8] : source_color;
  6. uniform float Tolerance[8];
  7. uniform int BlendMode[8];
  8. //#define DEBUG
  9. #ifdef DEBUG
  10. uniform sampler2D BlendTexture : source_color;
  11. #endif
  12. // ################################################################################################
  13. // ################################################################################################
  14. // ################################################################################################
  15. // ClusteringColor by CIEDE2000
  16. // https://www.shadertoy.com/view/msXyz8
  17. const float epsilon = 0.00001;
  18. float my_sin(float x) { return sin(radians(x)); }
  19. float my_cos(float x) { return cos(radians(x)); }
  20. float my_atan(float y, float x) {
  21. float v = degrees(atan(y, x));
  22. return (v < 0.0) ? v + 360.0 : v;
  23. }
  24. float get_h(float a, float b) {
  25. bool a_and_b_are_zeros = (abs(a) < epsilon)&&(abs(b) < epsilon);
  26. return a_and_b_are_zeros ? 0.0 : my_atan(b, a);
  27. }
  28. float get_delta_h(float C1, float C2, float h1, float h2) {
  29. float diff = h2 - h1;
  30. return (C1 * C2 < epsilon) ? 0.0 :
  31. (abs(diff) <= 180.0) ? diff :
  32. (diff > 180.0) ? diff - 360.0 :
  33. diff + 360.0;
  34. }
  35. float get_h_bar(float C1, float C2, float h1, float h2) {
  36. float dist = abs(h1 - h2);
  37. float sum = h1 + h2;
  38. return (C1 * C2 < epsilon) ? h1 + h2 :
  39. (dist <= 180.0) ? 0.5 * sum :
  40. (sum < 360.0) ? 0.5 * (sum + 360.0) :
  41. 0.5 * (sum - 360.0);
  42. }
  43. float calculate_CIEDE2000(vec3 Lab1, vec3 Lab2) {
  44. float L1 = Lab1.x;
  45. float a1 = Lab1.y;
  46. float b1 = Lab1.z;
  47. float L2 = Lab2.x;
  48. float a2 = Lab2.y;
  49. float b2 = Lab2.z;
  50. float C1_ab = sqrt(a1 * a1 + b1 * b1);
  51. float C2_ab = sqrt(a2 * a2 + b2 * b2);
  52. float C_ab_bar = 0.5 * (C1_ab + C2_ab);
  53. float G = 0.5 * (1.0 - sqrt(pow(C_ab_bar, 7.0) / (pow(C_ab_bar, 7.0) + pow(25.0, 7.0))));
  54. float a_1 = (1.0 + G) * a1;
  55. float a_2 = (1.0 + G) * a2;
  56. float C1 = sqrt(a_1 * a_1 + b1 * b1);
  57. float C2 = sqrt(a_2 * a_2 + b2 * b2);
  58. float h1 = get_h(a_1, b1);
  59. float h2 = get_h(a_2, b2);
  60. float delta_L = L2 - L1;
  61. float delta_C = C2 - C1;
  62. float delta_h = get_delta_h(C1, C2, h1, h2);
  63. float delta_H = 2.0 * sqrt(C1 * C2) * my_sin(0.5 * delta_h);
  64. float L_bar = 0.5 * (L1 + L2);
  65. float C_bar = 0.5 * (C1 + C2);
  66. float h_bar = get_h_bar(C1, C2, h1, h2);
  67. float T = 1.0 - 0.17 * my_cos(h_bar - 30.0) + 0.24 * my_cos(2.0 * h_bar) +
  68. 0.32 * my_cos(3.0 * h_bar + 6.0) - 0.20 * my_cos(4.0 * h_bar - 63.0);
  69. float delta_theta = 30.0 * exp(-((h_bar - 275.0) / 25.0) * ((h_bar - 275.0) / 25.0));
  70. float R_C = 2.0 * sqrt(pow(C_bar, 7.0) / (pow(C_bar, 7.0) + pow(25.0, 7.0)));
  71. float S_L = 1.0 + (0.015 * (L_bar - 50.0) * (L_bar - 50.0)) / sqrt(20.0 + (L_bar - 50.0) * (L_bar - 50.0));
  72. float S_C = 1.0 + 0.045 * C_bar;
  73. float S_H = 1.0 + 0.015 * C_bar * T;
  74. float R_T = -my_sin(2.0 * delta_theta) * R_C;
  75. const float k_L = 1.0;
  76. const float k_C = 1.0;
  77. const float k_H = 1.0;
  78. float deltaL = delta_L / (k_L * S_L);
  79. float deltaC = delta_C / (k_C * S_C);
  80. float deltaH = delta_H / (k_H * S_H);
  81. float delta_E_squared = deltaL * deltaL + deltaC * deltaC + deltaH * deltaH + R_T * deltaC * deltaH;
  82. return sqrt(delta_E_squared);
  83. }
  84. //--- RGB2Lab
  85. vec3 rgb2xyz(vec3 c) {
  86. vec3 tmp;
  87. tmp.x = (c.r > 0.04045) ? pow((c.r + 0.055) / 1.055, 2.4) : c.r / 12.92;
  88. tmp.y = (c.g > 0.04045) ? pow((c.g + 0.055) / 1.055, 2.4) : c.g / 12.92;
  89. tmp.z = (c.b > 0.04045) ? pow((c.b + 0.055) / 1.055, 2.4) : c.b / 12.92;
  90. return 100.0 * tmp * mat3(vec3(0.4124, 0.3576, 0.1805), vec3(0.2126, 0.7152, 0.0722), vec3(0.0193, 0.1192, 0.9505));
  91. }
  92. vec3 xyz2lab(vec3 c) {
  93. vec3 n = c / vec3(95.047, 100.0, 108.883);
  94. vec3 v;
  95. v.x = (n.x > 0.008856) ? pow(n.x, 1.0 / 3.0) : (7.787 * n.x) + (16.0 / 116.0);
  96. v.y = (n.y > 0.008856) ? pow(n.y, 1.0 / 3.0) : (7.787 * n.y) + (16.0 / 116.0);
  97. v.z = (n.z > 0.008856) ? pow(n.z, 1.0 / 3.0) : (7.787 * n.z) + (16.0 / 116.0);
  98. return vec3((116.0 * v.y) - 16.0, 500.0 * (v.x - v.y), 200.0 * (v.y - v.z));
  99. }
  100. vec3 rgb2lab(vec3 c) {
  101. vec3 lab = xyz2lab(rgb2xyz(c));
  102. return vec3(lab.x / 100.0, 0.5 + 0.5 * (lab.y / 127.0), 0.5 + 0.5 * (lab.z / 127.0));
  103. }
  104. float colorCompare(vec3 rgb1, vec3 rgb2) {
  105. vec3 lab1 = rgb2lab(rgb1);
  106. vec3 lab2 = rgb2lab(rgb2);
  107. return calculate_CIEDE2000(lab1, lab2);
  108. }
  109. // ################################################################################################
  110. // ################################################################################################
  111. // ################################################################################################
  112. // blends modes
  113. // https://en.wikipedia.org/wiki/Blend_modes
  114. // pdf page 389 blend mode: https://developer.adobe.com/document-services/docs/assets/5b15559b96303194340b99820d3a70fa/PDF_ISO_32000-2.pdf
  115. // functions
  116. #define VEC3(C, FUNC) vec3(FUNC(C.r), FUNC(C.g), FUNC(C.b))
  117. #define MAKE_VEC3(BASE, BLEND, FUNC) vec3(FUNC(BASE.r, BLEND.r), FUNC(BASE.g, BLEND.g), FUNC(BASE.b, BLEND.b))
  118. #define CMIN(C) min(C.r, min(C.g, C.b))
  119. #define CMAX(C) max(C.r, max(C.g, C.b))
  120. float unionAlpha(float b, float s) { return b + s * (1.0 - b); }
  121. float getLum(vec3 c) { return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b; } // Luminosity
  122. vec3 clipColor(vec3 c)
  123. {
  124. float l = getLum(c);
  125. float n = CMIN(c);
  126. float x = CMAX(c);
  127. if (n < 0.0) return l + (((c - l) * l) / (l - n));
  128. if (x > 1.0) return l + (((c - l) * (1.0 - l)) / (l - n));
  129. return c;
  130. }
  131. vec3 setLum(vec3 c, float l)
  132. {
  133. float d = l - getLum(c);
  134. c += d;
  135. return clipColor(c);
  136. }
  137. float getSat(vec3 c) { return CMAX(c) - CMIN(c); } // Saturation
  138. vec3 setSat(vec3 C, float s)
  139. {
  140. // subscripts for Cmin, Cmid, and Cmax
  141. int indices[3];
  142. if (C.x <= C.y) {
  143. if (C.y <= C.z) indices = int[3](0, 1, 2); // x <= y <= z
  144. else if (C.x <= C.z) indices = int[3](0, 2, 1); // x <= z < y
  145. else indices = int[3](2, 0, 1); // z < x <= y
  146. } else {
  147. if (C.x <= C.z) indices = int[3](1, 0, 2); // y < x <= z
  148. else if (C.y <= C.z)indices = int[3](1, 2, 0); // y <= z < x
  149. else indices = int[3](2, 1, 0); // z < y < x
  150. }
  151. // set Saturation
  152. if (C[indices[2]] > C[indices[0]])
  153. {
  154. C[indices[1]] = (((C[indices[1]] - C[indices[0]]) * s) / (C[indices[2]] - C[indices[0]]));
  155. C[indices[2]] = s;
  156. } else {
  157. C[indices[1]] = 0.0;
  158. C[indices[2]] = 0.0;
  159. }
  160. C[indices[0]] = 0.0;
  161. return C;
  162. }
  163. // 正常
  164. vec3 normal( vec3 Cb, vec3 Cs ) { return Cs; }
  165. // 正片叠底
  166. float _multiply( float Cb, float Cs ) { return Cb * Cs; }
  167. vec3 multiply( vec3 Cb, vec3 Cs ) { return Cb * Cs; }
  168. // 滤色
  169. float _screen( float Cb, float Cs ) { return Cb + Cs - Cb * Cs; }
  170. vec3 screen( vec3 Cb, vec3 Cs ) { return Cb + Cs - Cb * Cs; }
  171. // 变暗
  172. vec3 darken( vec3 Cb, vec3 Cs ) { return min(Cb, Cs); }
  173. // 变亮
  174. vec3 lighten( vec3 Cb, vec3 Cs ) { return max(Cb, Cs); }
  175. // 颜色减淡
  176. float _colorDodge( float Cb, float Cs )
  177. {
  178. if(Cb <= 0.0) return 0.0;
  179. else if (Cb >= (1.0 - Cs)) return 1.0;
  180. else return Cb / (1.0 - Cs);
  181. }
  182. vec3 colorDodge( vec3 Cb, vec3 Cs ) { return MAKE_VEC3(Cb, Cs, _colorDodge); }
  183. // 颜色加深
  184. float _colorBurn(float Cb, float Cs)
  185. {
  186. if (Cb >= 1.0) return 1.0;
  187. if ((1.0 - Cb) >= Cs) return 0.0;
  188. else return 1.0 - ((1.0 - Cb) / Cs);
  189. }
  190. vec3 colorBurn( vec3 Cb, vec3 Cs) { return MAKE_VEC3(Cb, Cs, _colorBurn); }
  191. // 强光
  192. float _hardLight( float Cb, float Cs ) { return (Cs <= 0.5) ? _multiply(Cb, 2.0 * Cs): _screen(Cb, 2.0 * Cs - 1.0); }
  193. vec3 hardLight( vec3 Cb, vec3 Cs ) { return MAKE_VEC3(Cb, Cs, _hardLight); }
  194. // 柔光
  195. float _softLight( float Cb, float Cs )
  196. {
  197. if(Cs <= 0.5) return Cb - (1.0 - 2.0 * Cs) * Cb * (1.0 - Cb);
  198. else
  199. {
  200. float d = (Cb <= 0.25) ? ((16.0 * Cb - 12.0) * Cb + 4.0) * Cb : sqrt(Cb);
  201. return Cb + (2.0 * Cs - 1.0) * (d - Cb);
  202. }
  203. }
  204. vec3 softLight( vec3 Cb, vec3 Cs ) { return MAKE_VEC3(Cb, Cs, _softLight); }
  205. // 叠加
  206. vec3 overlay( vec3 Cb, vec3 Cs ) { return hardLight(Cs, Cb); }
  207. // 差值
  208. vec3 difference( vec3 Cb, vec3 Cs ) { return abs(Cb - Cs); }
  209. // 排除
  210. vec3 exclusion( vec3 Cb, vec3 Cs ) { return Cb + Cs - 2.0 * Cb * Cs; }
  211. // 色相
  212. vec3 hue( vec3 Cb, vec3 Cs ) { return setLum(setSat(Cs, getSat(Cb)), getLum(Cb)); }
  213. // 颜色
  214. vec3 color( vec3 Cb, vec3 Cs ) { return setLum(Cs, getLum(Cb)); }
  215. // 饱和度
  216. vec3 saturation( vec3 Cb, vec3 Cs ) { return setLum(setSat(Cb, getSat(Cs)), getLum(Cb)); }
  217. // 明度
  218. vec3 luminosity( vec3 Cb, vec3 Cs ) { return setLum(Cb, getLum(Cs)); }
  219. // 剩下的不在pdf标准中
  220. // 线性加深
  221. float _linearBurn(float Cb, float Cs) { return max(0, Cb + Cs - 1.0); }
  222. vec3 linearBurn( vec3 Cb, vec3 Cs ) { return MAKE_VEC3(Cb, Cs, _linearBurn); }
  223. // 深色
  224. vec3 darkerColor( vec3 Cb, vec3 Cs ) { return getLum(Cb) < getLum(Cs)? Cb: Cs; }
  225. // 线性减淡(添加)
  226. float _linearDodge(float Cb, float Cs) { return min(1.0, Cb + Cs); }
  227. vec3 linearDodge( vec3 Cb, vec3 Cs ) { return MAKE_VEC3(Cb, Cs, _linearDodge); }
  228. // 浅色
  229. vec3 lighterColor( vec3 Cb, vec3 Cs ) { return getLum(Cb) > getLum(Cs)? Cb: Cs; }
  230. // 亮光
  231. float _vividLight( float Cb, float Cs ) { return (Cs <= 0.5) ? _colorBurn(Cb, 2.0 * Cs): _colorDodge(Cb, 2.0 * (Cs - 0.5)); }
  232. vec3 vividLight( vec3 Cb, vec3 Cs ) { return MAKE_VEC3(Cb, Cs, _vividLight); }
  233. // 线性光
  234. float _linearLight( float Cb, float Cs ) { return (Cs <= 0.5) ? _linearBurn(Cb, 2.0 * Cs): _linearDodge(Cb, 2.0 * (Cs - 0.5)); }
  235. vec3 linearLight( vec3 Cb, vec3 Cs ) { return MAKE_VEC3(Cb, Cs, _linearLight); }
  236. // 点光
  237. float _pinLight( float Cb, float Cs ) { return (Cs <= 0.5) ? min(Cb,2.0 * Cs) : max(Cb,2.0 * (Cs - 0.5)); }
  238. vec3 pinLight( vec3 Cb, vec3 Cs ) { return MAKE_VEC3(Cb, Cs, _pinLight); }
  239. // 实色混合
  240. float _hardMix( float Cb, float Cs ) { return (Cb + Cs >= 1.0) ? 1.0 : 0.0; }
  241. vec3 hardMix( vec3 Cb, vec3 Cs ) { return MAKE_VEC3(Cb, Cs, _hardMix); }
  242. // 减去
  243. vec3 subtract( vec3 Cb, vec3 Cs ) { return max(vec3(0.0), Cb - Cs); }
  244. // 划分
  245. float _divide( float Cb, float Cs ) { return Cs > 0.0 ? min(1.0, Cb / Cs) : 1.0; }
  246. vec3 divide( vec3 Cb, vec3 Cs ) { return MAKE_VEC3(Cb, Cs, _divide); }
  247. vec3 blendFunctions( vec3 Cb, vec3 Cs, int id )
  248. {
  249. if(id==0) return normal(Cb,Cs); // 正常
  250. if(id==1) return darken(Cb,Cs); // 变暗
  251. if(id==2) return multiply(Cb,Cs); // 正片叠底
  252. if(id==3) return colorBurn(Cb,Cs); // 颜色加深
  253. if(id==4) return linearBurn(Cb,Cs); // 线性加深
  254. if(id==5) return darkerColor(Cb,Cs); // 深色
  255. if(id==6) return lighten(Cb,Cs); // 变亮
  256. if(id==7) return screen(Cb,Cs); // 滤色
  257. if(id==8) return colorDodge(Cb,Cs); // 颜色减淡
  258. if(id==9) return linearDodge(Cb,Cs); // 线性减淡(添加)
  259. if(id==10) return lighterColor(Cb,Cs); // 浅色
  260. if(id==11) return overlay(Cb,Cs); // 叠加
  261. if(id==12) return softLight(Cb,Cs); // 柔光
  262. if(id==13) return hardLight(Cb,Cs); // 强光
  263. if(id==14) return vividLight(Cb,Cs); // 亮光
  264. if(id==15) return linearLight(Cb,Cs); // 线性光
  265. if(id==16) return pinLight(Cb,Cs); // 点光
  266. if(id==17) return hardMix(Cb,Cs); // 实色混合
  267. if(id==18) return difference(Cb,Cs); // 差值
  268. if(id==19) return exclusion(Cb,Cs); // 排除
  269. if(id==20) return subtract(Cb,Cs); // 减去
  270. if(id==21) return divide(Cb,Cs); // 划分
  271. if(id==22) return hue(Cb,Cs); // 色相
  272. if(id==23) return saturation(Cb,Cs); // 饱和度
  273. if(id==24) return color(Cb,Cs); // 颜色
  274. if(id==25) return luminosity(Cb,Cs); // 明度
  275. return vec3(0.0);
  276. }
  277. // ################################################################################################
  278. // ################################################################################################
  279. // ################################################################################################
  280. // gd shader script
  281. void fragment() {
  282. COLOR = texture(TEXTURE, UV);
  283. for (int i =0; i< PaletteCount; i++)
  284. {
  285. vec4 modulate_color = ModulateColor[i];
  286. vec4 basic_color = BasicColor[i];
  287. int blend_mode = BlendMode[i];
  288. float tolerance = Tolerance[i];
  289. // 将容差转换为0-1范围的阈值
  290. float tolerance_factor = tolerance / 100.0;
  291. // Backdrop colour 背景色
  292. vec3 Cb = COLOR.rgb;
  293. float Ab = COLOR.a;
  294. // Source colour 混合色
  295. #ifdef DEBUG
  296. vec4 source_colour = texture(BlendTexture, UV);
  297. vec3 Cs = source_colour.rgb;
  298. float As = source_colour.a;
  299. #else
  300. vec4 source_colour = modulate_color;
  301. vec3 Cs = source_colour.rgb;
  302. float As = Ab > 0.0? source_colour.a: 0.0;
  303. #endif
  304. // Result colour
  305. float Ar = unionAlpha(Ab, As);
  306. vec3 Cr = (1.0 - As / Ar) * Cb + As / Ar * ((1.0 - Ab) * Cs + Ab * blendFunctions(Cb, Cs, blend_mode));
  307. // 混合原始颜色和调制后的颜色
  308. if (tolerance_factor >= 1.0)
  309. COLOR = vec4(Cr, Ar);
  310. else
  311. {
  312. // 计算颜色差异
  313. float dis = colorCompare(Cb, basic_color.rgb);
  314. if (dis < tolerance_factor)
  315. COLOR = vec4(Cr, Ar);
  316. }
  317. }
  318. }