| 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 | |