blob: 55645331bba8fdf70f80199cf1c101400bcb38b6 [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <impeller/constants.glsl>
#include <impeller/branching.glsl>
vec3 BlendScreen(vec3 dst, vec3 src) {
return dst + src - (dst * src);
}
vec3 BlendHardLight(vec3 dst, vec3 src) {
return IPVec3Choose(dst * (2 * src), BlendScreen(dst, 2 * src - 1), src);
}
//------------------------------------------------------------------------------
// HSV utilities.
//
float Luminosity(vec3 color) {
return color.r * 0.3 + color.g * 0.59 + color.b * 0.11;
}
/// Scales the color's luma by the amount necessary to place the color
/// components in a 1-0 range.
vec3 ClipColor(vec3 color) {
float lum = Luminosity(color);
float mn = min(min(color.r, color.g), color.b);
float mx = max(max(color.r, color.g), color.b);
// `lum - mn` and `mx - lum` will always be >= 0 in the following conditions,
// so adding a tiny value is enough to make these divisions safe.
if (mn < 0) {
color = lum + (((color - lum) * lum) / (lum - mn + kEhCloseEnough));
}
if (mx > 1) {
color = lum + (((color - lum) * (1 - lum)) / (mx - lum + kEhCloseEnough));
}
return color;
}
vec3 SetLuminosity(vec3 color, float luminosity) {
float relative_lum = luminosity - Luminosity(color);
return ClipColor(color + relative_lum);
}
float Saturation(vec3 color) {
return max(max(color.r, color.g), color.b) -
min(min(color.r, color.g), color.b);
}
vec3 SetSaturation(vec3 color, float saturation) {
float mn = min(min(color.r, color.g), color.b);
float mx = max(max(color.r, color.g), color.b);
return (mn < mx) ? ((color - mn) * saturation) / (mx - mn) : vec3(0);
}