1 | // Aseprite |
2 | // Copyright (C) 2022 Igara Studio S.A. |
3 | // |
4 | // This program is distributed under the terms of |
5 | // the End-User License Agreement for Aseprite. |
6 | |
7 | #ifndef APP_UTIL_SHADER_HELPERS_H_INCLUDED |
8 | #define APP_UTIL_SHADER_HELPERS_H_INCLUDED |
9 | #pragma once |
10 | |
11 | #if SK_ENABLE_SKSL |
12 | |
13 | #include "app/color.h" |
14 | #include "gfx/color.h" |
15 | |
16 | #include "include/core/SkM44.h" |
17 | |
18 | // To include kRGB_to_HSL_sksl and kHSL_to_RGB_sksl |
19 | #include "src/core/SkRuntimeEffectPriv.h" |
20 | |
21 | namespace app { |
22 | |
23 | // rgb_to_hsl() and hsv_to_hsl() functions by Sam Hocevar licensed |
24 | // under WTFPL (https://en.wikipedia.org/wiki/WTFPL) |
25 | // Source: |
26 | // http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl |
27 | // https://stackoverflow.com/a/17897228/408239 |
28 | |
29 | inline constexpr char kRGB_to_HSV_sksl[] = R"( |
30 | half3 rgb_to_hsv(half3 c) { |
31 | half4 K = half4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); |
32 | half4 p = mix(half4(c.bg, K.wz), half4(c.gb, K.xy), step(c.b, c.g)); |
33 | half4 q = mix(half4(p.xyw, c.r), half4(c.r, p.yzx), step(p.x, c.r)); |
34 | |
35 | float d = q.x - min(q.w, q.y); |
36 | float e = 1.0e-10; |
37 | return half3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); |
38 | } |
39 | )" ; |
40 | |
41 | inline constexpr char kHSV_to_RGB_sksl[] = R"( |
42 | half3 hsv_to_rgb(half3 c) { |
43 | half4 K = half4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); |
44 | half3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); |
45 | return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); |
46 | } |
47 | )" ; |
48 | |
49 | inline SkV4 gfxColor_to_SkV4(gfx::Color color) { |
50 | return SkV4{float(gfx::getr(color) / 255.0), |
51 | float(gfx::getg(color) / 255.0), |
52 | float(gfx::getb(color) / 255.0), |
53 | float(gfx::geta(color) / 255.0)}; |
54 | } |
55 | |
56 | inline SkV4 appColor_to_SkV4(const app::Color& color) { |
57 | return SkV4{float(color.getRed() / 255.0), |
58 | float(color.getGreen() / 255.0), |
59 | float(color.getBlue() / 255.0), |
60 | float(color.getAlpha() / 255.0)}; |
61 | } |
62 | |
63 | inline SkV4 appColorHsv_to_SkV4(const app::Color& color) { |
64 | return SkV4{float(color.getHsvHue() / 360.0), |
65 | float(color.getHsvSaturation()), |
66 | float(color.getHsvValue()), |
67 | float(color.getAlpha() / 255.0)}; |
68 | } |
69 | |
70 | inline SkV4 appColorHsl_to_SkV4(const app::Color& color) { |
71 | return SkV4{float(color.getHslHue() / 360.0), |
72 | float(color.getHslSaturation()), |
73 | float(color.getHslLightness()), |
74 | float(color.getAlpha() / 255.0)}; |
75 | } |
76 | |
77 | } // namespace app |
78 | |
79 | #endif |
80 | |
81 | #endif |
82 | |