*/}}

la_tns_shaders.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. #include "la_5.h"
  2. extern "C" const char* TNS_SHADER_COLOR_COMMON=R"(
  3. #define M_PI 3.1415926535897932384626433832795
  4. float cbrt( float x ){
  5. return sign(x)*pow(abs(x),1.0f/3.0f);
  6. }
  7. float srgb_transfer_function(float a){
  8. return .0031308f >= a ? 12.92f * a : 1.055f * pow(a, .4166666666666667f) - .055f;
  9. }
  10. float srgb_transfer_function_inv(float a){
  11. return .04045f < a ? pow((a + .055f) / 1.055f, 2.4f) : a / 12.92f;
  12. }
  13. vec3 to_log_srgb(vec3 color){
  14. return vec3(srgb_transfer_function(color.r),srgb_transfer_function(color.g),srgb_transfer_function(color.b));
  15. }
  16. vec3 to_linear_srgb(vec3 color){
  17. return vec3(srgb_transfer_function_inv(color.r),srgb_transfer_function_inv(color.g),srgb_transfer_function_inv(color.b));
  18. }
  19. vec3 linear_srgb_to_oklab(vec3 c){
  20. float l = 0.4122214708f * c.r + 0.5363325363f * c.g + 0.0514459929f * c.b;
  21. float m = 0.2119034982f * c.r + 0.6806995451f * c.g + 0.1073969566f * c.b;
  22. float s = 0.0883024619f * c.r + 0.2817188376f * c.g + 0.6299787005f * c.b;
  23. float l_ = cbrt(l);
  24. float m_ = cbrt(m);
  25. float s_ = cbrt(s);
  26. return vec3(
  27. 0.2104542553f * l_ + 0.7936177850f * m_ - 0.0040720468f * s_,
  28. 1.9779984951f * l_ - 2.4285922050f * m_ + 0.4505937099f * s_,
  29. 0.0259040371f * l_ + 0.7827717662f * m_ - 0.8086757660f * s_
  30. );
  31. }
  32. vec3 oklab_to_linear_srgb(vec3 c){
  33. float l_ = c.x + 0.3963377774f * c.y + 0.2158037573f * c.z;
  34. float m_ = c.x - 0.1055613458f * c.y - 0.0638541728f * c.z;
  35. float s_ = c.x - 0.0894841775f * c.y - 1.2914855480f * c.z;
  36. float l = l_ * l_ * l_;
  37. float m = m_ * m_ * m_;
  38. float s = s_ * s_ * s_;
  39. return vec3(
  40. +4.0767416621f * l - 3.3077115913f * m + 0.2309699292f * s,
  41. -1.2684380046f * l + 2.6097574011f * m - 0.3413193965f * s,
  42. -0.0041960863f * l - 0.7034186147f * m + 1.7076147010f * s
  43. );
  44. }
  45. float compute_max_saturation(float a, float b){ float k0, k1, k2, k3, k4, wl, wm, ws;
  46. if (-1.88170328f * a - 0.80936493f * b > 1.f){ k0 = +1.19086277f; k1 = +1.76576728f; k2 = +0.59662641f; k3 = +0.75515197f; k4 = +0.56771245f;
  47. wl = +4.0767416621f; wm = -3.3077115913f; ws = +0.2309699292f;
  48. }
  49. else if (1.81444104f * a - 1.19445276f * b > 1.f){ k0 = +0.73956515f; k1 = -0.45954404f; k2 = +0.08285427f; k3 = +0.12541070f; k4 = +0.14503204f;
  50. wl = -1.2684380046f; wm = +2.6097574011f; ws = -0.3413193965f;
  51. }
  52. else{ k0 = +1.35733652f; k1 = -0.00915799f; k2 = -1.15130210f; k3 = -0.50559606f; k4 = +0.00692167f;
  53. wl = -0.0041960863f; wm = -0.7034186147f; ws = +1.7076147010f;
  54. } float S = k0 + k1 * a + k2 * b + k3 * a * a + k4 * a * b;
  55. float k_l = +0.3963377774f * a + 0.2158037573f * b;
  56. float k_m = -0.1055613458f * a - 0.0638541728f * b;
  57. float k_s = -0.0894841775f * a - 1.2914855480f * b;{
  58. float l_ = 1.f + S * k_l;
  59. float m_ = 1.f + S * k_m;
  60. float s_ = 1.f + S * k_s;
  61. float l = l_ * l_ * l_;
  62. float m = m_ * m_ * m_;
  63. float s = s_ * s_ * s_;
  64. float l_dS = 3.f * k_l * l_ * l_;
  65. float m_dS = 3.f * k_m * m_ * m_;
  66. float s_dS = 3.f * k_s * s_ * s_;
  67. float l_dS2 = 6.f * k_l * k_l * l_;
  68. float m_dS2 = 6.f * k_m * k_m * m_;
  69. float s_dS2 = 6.f * k_s * k_s * s_;
  70. float f = wl * l + wm * m + ws * s;
  71. float f1 = wl * l_dS + wm * m_dS + ws * s_dS;
  72. float f2 = wl * l_dS2 + wm * m_dS2 + ws * s_dS2;
  73. S = S - f * f1 / (f1 * f1 - 0.5f * f * f2);
  74. }
  75. return S;
  76. }
  77. vec2 find_cusp(float a, float b){ float S_cusp = compute_max_saturation(a, b); vec3 rgb_at_max = oklab_to_linear_srgb(vec3( 1, S_cusp * a, S_cusp * b ));
  78. float L_cusp = cbrt(1.f / max(max(rgb_at_max.r, rgb_at_max.g), rgb_at_max.b));
  79. float C_cusp = L_cusp * S_cusp;
  80. return vec2( L_cusp , C_cusp );
  81. }
  82. float find_gamut_intersection(float a, float b, float L1, float C1, float L0, vec2 cusp){ float t;
  83. if (((L1 - L0) * cusp.y - (cusp.x - L0) * C1) <= 0.f){
  84. t = cusp.y * L0 / (C1 * cusp.x + cusp.y * (L0 - L1));
  85. }
  86. else{ t = cusp.y * (L0 - 1.f) / (C1 * (cusp.x - 1.f) + cusp.y * (L0 - L1)); {
  87. float dL = L1 - L0;
  88. float dC = C1;
  89. float k_l = +0.3963377774f * a + 0.2158037573f * b;
  90. float k_m = -0.1055613458f * a - 0.0638541728f * b;
  91. float k_s = -0.0894841775f * a - 1.2914855480f * b;
  92. float l_dt = dL + dC * k_l;
  93. float m_dt = dL + dC * k_m;
  94. float s_dt = dL + dC * k_s; {
  95. float L = L0 * (1.f - t) + t * L1;
  96. float C = t * C1;
  97. float l_ = L + C * k_l;
  98. float m_ = L + C * k_m;
  99. float s_ = L + C * k_s;
  100. float l = l_ * l_ * l_;
  101. float m = m_ * m_ * m_;
  102. float s = s_ * s_ * s_;
  103. float ldt = 3.f * l_dt * l_ * l_;
  104. float mdt = 3.f * m_dt * m_ * m_;
  105. float sdt = 3.f * s_dt * s_ * s_;
  106. float ldt2 = 6.f * l_dt * l_dt * l_;
  107. float mdt2 = 6.f * m_dt * m_dt * m_;
  108. float sdt2 = 6.f * s_dt * s_dt * s_;
  109. float r = 4.0767416621f * l - 3.3077115913f * m + 0.2309699292f * s - 1.f;
  110. float r1 = 4.0767416621f * ldt - 3.3077115913f * mdt + 0.2309699292f * sdt;
  111. float r2 = 4.0767416621f * ldt2 - 3.3077115913f * mdt2 + 0.2309699292f * sdt2;
  112. float u_r = r1 / (r1 * r1 - 0.5f * r * r2);
  113. float t_r = -r * u_r;
  114. float g = -1.2684380046f * l + 2.6097574011f * m - 0.3413193965f * s - 1.f;
  115. float g1 = -1.2684380046f * ldt + 2.6097574011f * mdt - 0.3413193965f * sdt;
  116. float g2 = -1.2684380046f * ldt2 + 2.6097574011f * mdt2 - 0.3413193965f * sdt2;
  117. float u_g = g1 / (g1 * g1 - 0.5f * g * g2);
  118. float t_g = -g * u_g;
  119. float b = -0.0041960863f * l - 0.7034186147f * m + 1.7076147010f * s - 1.f;
  120. float b1 = -0.0041960863f * ldt - 0.7034186147f * mdt + 1.7076147010f * sdt;
  121. float b2 = -0.0041960863f * ldt2 - 0.7034186147f * mdt2 + 1.7076147010f * sdt2;
  122. float u_b = b1 / (b1 * b1 - 0.5f * b * b2);
  123. float t_b = -b * u_b;
  124. t_r = u_r >= 0.f ? t_r : 10000.f;
  125. t_g = u_g >= 0.f ? t_g : 10000.f;
  126. t_b = u_b >= 0.f ? t_b : 10000.f;
  127. t += min(t_r, min(t_g, t_b));
  128. }
  129. }
  130. }
  131. return t;
  132. }
  133. float find_gamut_intersection(float a, float b, float L1, float C1, float L0){ vec2 cusp = find_cusp(a, b);
  134. return find_gamut_intersection(a, b, L1, C1, L0, cusp);
  135. }
  136. vec3 gamut_clip_preserve_chroma(vec3 rgb){
  137. if (rgb.r < 1.f && rgb.g < 1.f && rgb.b < 1.f && rgb.r > 0.f && rgb.g > 0.f && rgb.b > 0.f)
  138. return rgb;
  139. vec3 lab = linear_srgb_to_oklab(rgb);
  140. float L = lab.x;
  141. float eps = 0.00001f;
  142. float C = max(eps, sqrt(lab.y * lab.y + lab.z * lab.z));
  143. float a_ = lab.y / C;
  144. float b_ = lab.z / C;
  145. float L0 = clamp(L, 0.f, 1.f);
  146. float t = find_gamut_intersection(a_, b_, L, C, L0);
  147. float L_clipped = L0 * (1.f - t) + t * L;
  148. float C_clipped = t * C;
  149. return oklab_to_linear_srgb(vec3( L_clipped, C_clipped * a_, C_clipped * b_ ));
  150. }
  151. vec3 gamut_clip_project_to_0_5(vec3 rgb){
  152. if (rgb.r < 1.f && rgb.g < 1.f && rgb.b < 1.f && rgb.r > 0.f && rgb.g > 0.f && rgb.b > 0.f)
  153. return rgb;
  154. vec3 lab = linear_srgb_to_oklab(rgb);
  155. float L = lab.x;
  156. float eps = 0.00001f;
  157. float C = max(eps, sqrt(lab.y * lab.y + lab.z * lab.z));
  158. float a_ = lab.y / C;
  159. float b_ = lab.z / C;
  160. float L0 = 0.5;
  161. float t = find_gamut_intersection(a_, b_, L, C, L0);
  162. float L_clipped = L0 * (1.f - t) + t * L;
  163. float C_clipped = t * C;
  164. return oklab_to_linear_srgb(vec3( L_clipped, C_clipped * a_, C_clipped * b_ ));
  165. }
  166. vec3 gamut_clip_project_to_L_cusp(vec3 rgb){
  167. if (rgb.r < 1.f && rgb.g < 1.f && rgb.b < 1.f && rgb.r > 0.f && rgb.g > 0.f && rgb.b > 0.f)
  168. return rgb;
  169. vec3 lab = linear_srgb_to_oklab(rgb);
  170. float L = lab.x;
  171. float eps = 0.00001f;
  172. float C = max(eps, sqrt(lab.y * lab.y + lab.z * lab.z));
  173. float a_ = lab.y / C;
  174. float b_ = lab.z / C; vec2 cusp = find_cusp(a_, b_);
  175. float L0 = cusp.x;
  176. float t = find_gamut_intersection(a_, b_, L, C, L0);
  177. float L_clipped = L0 * (1.f - t) + t * L;
  178. float C_clipped = t * C;
  179. return oklab_to_linear_srgb(vec3( L_clipped, C_clipped * a_, C_clipped * b_ ));
  180. }
  181. vec3 gamut_clip_adaptive_L0_0_5(vec3 rgb, float alpha){
  182. if (rgb.r < 1.f && rgb.g < 1.f && rgb.b < 1.f && rgb.r > 0.f && rgb.g > 0.f && rgb.b > 0.f)
  183. return rgb;
  184. vec3 lab = linear_srgb_to_oklab(rgb);
  185. float L = lab.x;
  186. float eps = 0.00001f;
  187. float C = max(eps, sqrt(lab.y * lab.y + lab.z * lab.z));
  188. float a_ = lab.y / C;
  189. float b_ = lab.z / C;
  190. float Ld = L - 0.5f;
  191. float e1 = 0.5f + abs(Ld) + alpha * C;
  192. float L0 = 0.5f * (1.f + sign(Ld) * (e1 - sqrt(e1 * e1 - 2.f * abs(Ld))));
  193. float t = find_gamut_intersection(a_, b_, L, C, L0);
  194. float L_clipped = L0 * (1.f - t) + t * L;
  195. float C_clipped = t * C;
  196. return oklab_to_linear_srgb(vec3( L_clipped, C_clipped * a_, C_clipped * b_ ));
  197. }
  198. vec3 gamut_clip_adaptive_L0_L_cusp(vec3 rgb, float alpha){
  199. if (rgb.r < 1.f && rgb.g < 1.f && rgb.b < 1.f && rgb.r > 0.f && rgb.g > 0.f && rgb.b > 0.f)
  200. return rgb;
  201. vec3 lab = linear_srgb_to_oklab(rgb);
  202. float L = lab.x;
  203. float eps = 0.00001f;
  204. float C = max(eps, sqrt(lab.y * lab.y + lab.z * lab.z));
  205. float a_ = lab.y / C;
  206. float b_ = lab.z / C; vec2 cusp = find_cusp(a_, b_);
  207. float Ld = L - cusp.x;
  208. float k = 2.f * (Ld > 0.f ? 1.f - cusp.x : cusp.x);
  209. float e1 = 0.5f * k + abs(Ld) + alpha * C / k;
  210. float L0 = cusp.x + 0.5f * (sign(Ld) * (e1 - sqrt(e1 * e1 - 2.f * k * abs(Ld))));
  211. float t = find_gamut_intersection(a_, b_, L, C, L0);
  212. float L_clipped = L0 * (1.f - t) + t * L;
  213. float C_clipped = t * C;
  214. return oklab_to_linear_srgb(vec3( L_clipped, C_clipped * a_, C_clipped * b_ ));
  215. }
  216. float toe(float x){
  217. float k_1 = 0.206f;
  218. float k_2 = 0.03f;
  219. float k_3 = (1.f + k_1) / (1.f + k_2);
  220. return 0.5f * (k_3 * x - k_1 + sqrt((k_3 * x - k_1) * (k_3 * x - k_1) + 4.f * k_2 * k_3 * x));
  221. }
  222. float toe_inv(float x){
  223. float k_1 = 0.206f;
  224. float k_2 = 0.03f;
  225. float k_3 = (1.f + k_1) / (1.f + k_2);
  226. return (x * x + k_1 * x) / (k_3 * (x + k_2));
  227. }
  228. vec2 to_ST(vec2 cusp){
  229. float L = cusp.x;
  230. float C = cusp.y;
  231. return vec2( C / L, C / (1.f - L) );
  232. }
  233. vec2 get_ST_mid(float a_, float b_){
  234. float S = 0.11516993f + 1.f / (
  235. +7.44778970f + 4.15901240f * b_
  236. + a_ * (-2.19557347f + 1.75198401f * b_
  237. + a_ * (-2.13704948f - 10.02301043f * b_
  238. + a_ * (-4.24894561f + 5.38770819f * b_ + 4.69891013f * a_
  239. )))
  240. );
  241. float T = 0.11239642f + 1.f / (
  242. +1.61320320f - 0.68124379f * b_
  243. + a_ * (+0.40370612f + 0.90148123f * b_
  244. + a_ * (-0.27087943f + 0.61223990f * b_
  245. + a_ * (+0.00299215f - 0.45399568f * b_ - 0.14661872f * a_
  246. )))
  247. );
  248. return vec2( S, T );
  249. }
  250. vec3 get_Cs(float L, float a_, float b_){
  251. vec2 cusp = find_cusp(a_, b_);
  252. float C_max = find_gamut_intersection(a_, b_, L, 1.f, L, cusp);
  253. vec2 ST_max = to_ST(cusp); float k = C_max / min((L * ST_max.x), (1.f - L) * ST_max.y);
  254. float C_mid;{
  255. vec2 ST_mid = get_ST_mid(a_, b_); float C_a = L * ST_mid.x;
  256. float C_b = (1.f - L) * ST_mid.y;
  257. C_mid = 0.9f * k * sqrt(sqrt(1.f / (1.f / (C_a * C_a * C_a * C_a) + 1.f / (C_b * C_b * C_b * C_b))));
  258. }
  259. float C_0;{ float C_a = L * 0.4f;
  260. float C_b = (1.f - L) * 0.8f; C_0 = sqrt(1.f / (1.f / (C_a * C_a) + 1.f / (C_b * C_b)));
  261. }
  262. return vec3( C_0, C_mid, C_max );
  263. }
  264. vec3 okhsl_to_srgb(vec3 hsl){
  265. float h = hsl.x;
  266. float s = hsl.y;
  267. float l = hsl.z;
  268. if (l == 1.0f){
  269. return vec3( 1.f, 1.f, 1.f );
  270. }
  271. else if (l == 0.f){
  272. return vec3( 0.f, 0.f, 0.f );
  273. }
  274. float a_ = cos(2.f * M_PI * h);
  275. float b_ = sin(2.f * M_PI * h);
  276. float L = toe_inv(l);
  277. vec3 cs = get_Cs(L, a_, b_);
  278. float C_0 = cs.x;
  279. float C_mid = cs.y;
  280. float C_max = cs.z;
  281. float mid = 0.8f;
  282. float mid_inv = 1.25f;
  283. float C, t, k_0, k_1, k_2;
  284. if (s < mid){
  285. t = mid_inv * s;
  286. k_1 = mid * C_0;
  287. k_2 = (1.f - k_1 / C_mid);
  288. C = t * k_1 / (1.f - k_2 * t);
  289. }
  290. else{
  291. t = (s - mid)/ (1.f - mid);
  292. k_0 = C_mid;
  293. k_1 = (1.f - mid) * C_mid * C_mid * mid_inv * mid_inv / C_0;
  294. k_2 = (1.f - (k_1) / (C_max - C_mid));
  295. C = k_0 + t * k_1 / (1.f - k_2 * t);
  296. }
  297. vec3 rgb = oklab_to_linear_srgb(vec3( L, C * a_, C * b_ ));
  298. return vec3(
  299. srgb_transfer_function(rgb.r),
  300. srgb_transfer_function(rgb.g),
  301. srgb_transfer_function(rgb.b)
  302. );
  303. }
  304. vec3 srgb_to_okhsl(vec3 rgb){
  305. vec3 lab = linear_srgb_to_oklab(vec3(
  306. srgb_transfer_function_inv(rgb.r),
  307. srgb_transfer_function_inv(rgb.g),
  308. srgb_transfer_function_inv(rgb.b)
  309. ));
  310. float C = sqrt(lab.y * lab.y + lab.z * lab.z);
  311. float a_ = lab.y / C;
  312. float b_ = lab.z / C;
  313. float L = lab.x;
  314. float h = 0.5f + 0.5f * atan(-lab.z, -lab.y) / M_PI;
  315. vec3 cs = get_Cs(L, a_, b_);
  316. float C_0 = cs.x;
  317. float C_mid = cs.y;
  318. float C_max = cs.z;
  319. float mid = 0.8f;
  320. float mid_inv = 1.25f;
  321. float s;
  322. if (C < C_mid){
  323. float k_1 = mid * C_0;
  324. float k_2 = (1.f - k_1 / C_mid);
  325. float t = C / (k_1 + k_2 * C);
  326. s = t * mid;
  327. }
  328. else{
  329. float k_0 = C_mid;
  330. float k_1 = (1.f - mid) * C_mid * C_mid * mid_inv * mid_inv / C_0;
  331. float k_2 = (1.f - (k_1) / (C_max - C_mid));
  332. float t = (C - k_0) / (k_1 + k_2 * (C - k_0));
  333. s = mid + (1.f - mid) * t;
  334. }
  335. float l = toe(L);
  336. return vec3( h, s, l );
  337. }
  338. vec3 okhsv_to_srgb(vec3 hsv){
  339. float h = hsv.x;
  340. float s = hsv.y;
  341. float v = hsv.z;
  342. float a_ = cos(2.f * M_PI * h);
  343. float b_ = sin(2.f * M_PI * h);
  344. vec2 cusp = find_cusp(a_, b_);
  345. vec2 ST_max = to_ST(cusp);
  346. float S_max = ST_max.x;
  347. float T_max = ST_max.y;
  348. float S_0 = 0.5f;
  349. float k = 1.f- S_0 / S_max; float L_v = 1.f - s * S_0 / (S_0 + T_max - T_max * k * s);
  350. float C_v = s * T_max * S_0 / (S_0 + T_max - T_max * k * s);
  351. float L = v * L_v;
  352. float C = v * C_v; float L_vt = toe_inv(L_v);
  353. float C_vt = C_v * L_vt / L_v;
  354. float L_new = toe_inv(L);
  355. C = C * L_new / L;
  356. L = L_new;
  357. vec3 rgb_scale = oklab_to_linear_srgb(vec3( L_vt, a_ * C_vt, b_ * C_vt ));
  358. float scale_L = cbrt(1.f / max(max(rgb_scale.r, rgb_scale.g), max(rgb_scale.b, 0.f)));
  359. L = L * scale_L;
  360. C = C * scale_L;
  361. vec3 rgb = oklab_to_linear_srgb(vec3( L, C * a_, C * b_ ));
  362. return vec3(
  363. srgb_transfer_function(rgb.r),
  364. srgb_transfer_function(rgb.g),
  365. srgb_transfer_function(rgb.b)
  366. );
  367. }
  368. vec3 srgb_to_okhsv(vec3 rgb){
  369. vec3 lab = linear_srgb_to_oklab(vec3(
  370. srgb_transfer_function_inv(rgb.r),
  371. srgb_transfer_function_inv(rgb.g),
  372. srgb_transfer_function_inv(rgb.b)
  373. ));
  374. float C = sqrt(lab.y * lab.y + lab.z * lab.z);
  375. float a_ = lab.y / C;
  376. float b_ = lab.z / C;
  377. float L = lab.x;
  378. float h = 0.5f + 0.5f * atan(-lab.z, -lab.y) / M_PI;
  379. vec2 cusp = find_cusp(a_, b_);
  380. vec2 ST_max = to_ST(cusp);
  381. float S_max = ST_max.x;
  382. float T_max = ST_max.y;
  383. float S_0 = 0.5f;
  384. float k = 1.f - S_0 / S_max;
  385. float t = T_max / (C + L * T_max);
  386. float L_v = t * L;
  387. float C_v = t * C;
  388. float L_vt = toe_inv(L_v);
  389. float C_vt = C_v * L_vt / L_v; vec3 rgb_scale = oklab_to_linear_srgb(vec3( L_vt, a_ * C_vt, b_ * C_vt ));
  390. float scale_L = cbrt(1.f / max(max(rgb_scale.r, rgb_scale.g), max(rgb_scale.b, 0.f)));
  391. L = L / scale_L;
  392. C = C / scale_L;
  393. C = C * toe(L) / L;
  394. L = toe(L);
  395. float v = L / L_v;
  396. float s = (S_0 + T_max) * C_v / ((T_max * S_0) + T_max * k * C_v);
  397. return vec3 (h, s, v );
  398. }
  399. )";