Add LCH(ab) color space to bevy_render::color::Color (#7483)
# Objective - Fixes #766 ## Solution - Add a new `Lcha` member to `bevy_render::color::Color` enum --- ## Changelog - Add a new `Lcha` member to `bevy_render::color::Color` enum - Add `bevy_render::color::LchRepresentation` struct
This commit is contained in:
parent
5b930c8486
commit
7b7b34f635
@ -102,6 +102,137 @@ impl HslRepresentation {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LchRepresentation;
|
||||
impl LchRepresentation {
|
||||
// References available at http://brucelindbloom.com/ in the "Math" section
|
||||
|
||||
// CIE Constants
|
||||
// http://brucelindbloom.com/index.html?LContinuity.html (16) (17)
|
||||
const CIE_EPSILON: f32 = 216.0 / 24389.0;
|
||||
const CIE_KAPPA: f32 = 24389.0 / 27.0;
|
||||
// D65 White Reference:
|
||||
// https://en.wikipedia.org/wiki/Illuminant_D65#Definition
|
||||
const D65_WHITE_X: f32 = 0.95047;
|
||||
const D65_WHITE_Y: f32 = 1.0;
|
||||
const D65_WHITE_Z: f32 = 1.08883;
|
||||
|
||||
/// converts a color in LCH space to sRGB space
|
||||
#[inline]
|
||||
pub fn lch_to_nonlinear_srgb(lightness: f32, chroma: f32, hue: f32) -> [f32; 3] {
|
||||
let lightness = lightness * 100.0;
|
||||
let chroma = chroma * 100.0;
|
||||
|
||||
// convert LCH to Lab
|
||||
// http://www.brucelindbloom.com/index.html?Eqn_LCH_to_Lab.html
|
||||
let l = lightness;
|
||||
let a = chroma * hue.to_radians().cos();
|
||||
let b = chroma * hue.to_radians().sin();
|
||||
|
||||
// convert Lab to XYZ
|
||||
// http://www.brucelindbloom.com/index.html?Eqn_Lab_to_XYZ.html
|
||||
let fy = (l + 16.0) / 116.0;
|
||||
let fx = a / 500.0 + fy;
|
||||
let fz = fy - b / 200.0;
|
||||
let xr = {
|
||||
let fx3 = fx.powf(3.0);
|
||||
|
||||
if fx3 > Self::CIE_EPSILON {
|
||||
fx3
|
||||
} else {
|
||||
(116.0 * fx - 16.0) / Self::CIE_KAPPA
|
||||
}
|
||||
};
|
||||
let yr = if l > Self::CIE_EPSILON * Self::CIE_KAPPA {
|
||||
((l + 16.0) / 116.0).powf(3.0)
|
||||
} else {
|
||||
l / Self::CIE_KAPPA
|
||||
};
|
||||
let zr = {
|
||||
let fz3 = fz.powf(3.0);
|
||||
|
||||
if fz3 > Self::CIE_EPSILON {
|
||||
fz3
|
||||
} else {
|
||||
(116.0 * fz - 16.0) / Self::CIE_KAPPA
|
||||
}
|
||||
};
|
||||
let x = xr * Self::D65_WHITE_X;
|
||||
let y = yr * Self::D65_WHITE_Y;
|
||||
let z = zr * Self::D65_WHITE_Z;
|
||||
|
||||
// XYZ to sRGB
|
||||
// http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_RGB.html
|
||||
// http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html (sRGB, XYZ to RGB [M]-1)
|
||||
let red = x * 3.2404542 + y * -1.5371385 + z * -0.4985314;
|
||||
let green = x * -0.969266 + y * 1.8760108 + z * 0.041556;
|
||||
let blue = x * 0.0556434 + y * -0.2040259 + z * 1.0572252;
|
||||
|
||||
[
|
||||
red.linear_to_nonlinear_srgb().max(0.0).min(1.0),
|
||||
green.linear_to_nonlinear_srgb().max(0.0).min(1.0),
|
||||
blue.linear_to_nonlinear_srgb().max(0.0).min(1.0),
|
||||
]
|
||||
}
|
||||
|
||||
/// converts a color in sRGB space to LCH space
|
||||
#[inline]
|
||||
pub fn nonlinear_srgb_to_lch([red, green, blue]: [f32; 3]) -> (f32, f32, f32) {
|
||||
// RGB to XYZ
|
||||
// http://www.brucelindbloom.com/index.html?Eqn_RGB_to_XYZ.html
|
||||
let red = red.nonlinear_to_linear_srgb();
|
||||
let green = green.nonlinear_to_linear_srgb();
|
||||
let blue = blue.nonlinear_to_linear_srgb();
|
||||
|
||||
// http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html (sRGB, RGB to XYZ [M])
|
||||
let x = red * 0.4124564 + green * 0.3575761 + blue * 0.1804375;
|
||||
let y = red * 0.2126729 + green * 0.7151522 + blue * 0.072175;
|
||||
let z = red * 0.0193339 + green * 0.119192 + blue * 0.9503041;
|
||||
|
||||
// XYZ to Lab
|
||||
// http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_Lab.html
|
||||
let xr = x / Self::D65_WHITE_X;
|
||||
let yr = y / Self::D65_WHITE_Y;
|
||||
let zr = z / Self::D65_WHITE_Z;
|
||||
let fx = if xr > Self::CIE_EPSILON {
|
||||
xr.cbrt()
|
||||
} else {
|
||||
(Self::CIE_KAPPA * xr + 16.0) / 116.0
|
||||
};
|
||||
let fy = if yr > Self::CIE_EPSILON {
|
||||
yr.cbrt()
|
||||
} else {
|
||||
(Self::CIE_KAPPA * yr + 16.0) / 116.0
|
||||
};
|
||||
let fz = if yr > Self::CIE_EPSILON {
|
||||
zr.cbrt()
|
||||
} else {
|
||||
(Self::CIE_KAPPA * zr + 16.0) / 116.0
|
||||
};
|
||||
let l = 116.0 * fy - 16.0;
|
||||
let a = 500.0 * (fx - fy);
|
||||
let b = 200.0 * (fy - fz);
|
||||
|
||||
// Lab to LCH
|
||||
// http://www.brucelindbloom.com/index.html?Eqn_Lab_to_LCH.html
|
||||
let c = (a.powf(2.0) + b.powf(2.0)).sqrt();
|
||||
let h = {
|
||||
let h = b.to_radians().atan2(a.to_radians()).to_degrees();
|
||||
|
||||
if h < 0.0 {
|
||||
h + 360.0
|
||||
} else {
|
||||
h
|
||||
}
|
||||
};
|
||||
|
||||
(
|
||||
(l / 100.0).max(0.0).min(1.5),
|
||||
(c / 100.0).max(0.0).min(1.5),
|
||||
h,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
@ -214,4 +345,90 @@ mod test {
|
||||
assert_eq!((saturation * 100.0).round() as u32, 83);
|
||||
assert_eq!((lightness * 100.0).round() as u32, 51);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lch_to_srgb() {
|
||||
// "truth" from http://www.brucelindbloom.com/ColorCalculator.html
|
||||
|
||||
// black
|
||||
let (lightness, chroma, hue) = (0.0, 0.0, 0.0);
|
||||
let [r, g, b] = LchRepresentation::lch_to_nonlinear_srgb(lightness, chroma, hue);
|
||||
assert_eq!((r * 100.0).round() as u32, 0);
|
||||
assert_eq!((g * 100.0).round() as u32, 0);
|
||||
assert_eq!((b * 100.0).round() as u32, 0);
|
||||
|
||||
// white
|
||||
let (lightness, chroma, hue) = (1.0, 0.0, 0.0);
|
||||
let [r, g, b] = LchRepresentation::lch_to_nonlinear_srgb(lightness, chroma, hue);
|
||||
assert_eq!((r * 100.0).round() as u32, 100);
|
||||
assert_eq!((g * 100.0).round() as u32, 100);
|
||||
assert_eq!((b * 100.0).round() as u32, 100);
|
||||
|
||||
let (lightness, chroma, hue) = (0.501236, 0.777514, 327.6608);
|
||||
let [r, g, b] = LchRepresentation::lch_to_nonlinear_srgb(lightness, chroma, hue);
|
||||
assert_eq!((r * 100.0).round() as u32, 75);
|
||||
assert_eq!((g * 100.0).round() as u32, 25);
|
||||
assert_eq!((b * 100.0).round() as u32, 75);
|
||||
|
||||
// a red
|
||||
let (lightness, chroma, hue) = (0.487122, 0.999531, 318.7684);
|
||||
let [r, g, b] = LchRepresentation::lch_to_nonlinear_srgb(lightness, chroma, hue);
|
||||
assert_eq!((r * 100.0).round() as u32, 70);
|
||||
assert_eq!((g * 100.0).round() as u32, 19);
|
||||
assert_eq!((b * 100.0).round() as u32, 90);
|
||||
|
||||
// a green
|
||||
let (lightness, chroma, hue) = (0.732929, 0.560925, 164.3216);
|
||||
let [r, g, b] = LchRepresentation::lch_to_nonlinear_srgb(lightness, chroma, hue);
|
||||
assert_eq!((r * 100.0).round() as u32, 10);
|
||||
assert_eq!((g * 100.0).round() as u32, 80);
|
||||
assert_eq!((b * 100.0).round() as u32, 59);
|
||||
|
||||
// a blue
|
||||
let (lightness, chroma, hue) = (0.335030, 1.176923, 306.7828);
|
||||
let [r, g, b] = LchRepresentation::lch_to_nonlinear_srgb(lightness, chroma, hue);
|
||||
assert_eq!((r * 100.0).round() as u32, 25);
|
||||
assert_eq!((g * 100.0).round() as u32, 10);
|
||||
assert_eq!((b * 100.0).round() as u32, 92);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn srgb_to_lch() {
|
||||
// "truth" from http://www.brucelindbloom.com/ColorCalculator.html
|
||||
|
||||
// black
|
||||
let (lightness, chroma, hue) = LchRepresentation::nonlinear_srgb_to_lch([0.0, 0.0, 0.0]);
|
||||
assert_eq!((lightness * 100.0).round() as u32, 0);
|
||||
assert_eq!((chroma * 100.0).round() as u32, 0);
|
||||
assert_eq!(hue.round() as u32, 0);
|
||||
|
||||
// white
|
||||
let (lightness, chroma, hue) = LchRepresentation::nonlinear_srgb_to_lch([1.0, 1.0, 1.0]);
|
||||
assert_eq!((lightness * 100.0).round() as u32, 100);
|
||||
assert_eq!((chroma * 100.0).round() as u32, 0);
|
||||
assert_eq!(hue.round() as u32, 0);
|
||||
|
||||
let (lightness, chroma, hue) = LchRepresentation::nonlinear_srgb_to_lch([0.75, 0.25, 0.75]);
|
||||
assert_eq!((lightness * 100.0).round() as u32, 50);
|
||||
assert_eq!((chroma * 100.0).round() as u32, 78);
|
||||
assert_eq!(hue.round() as u32, 328);
|
||||
|
||||
// a red
|
||||
let (lightness, chroma, hue) = LchRepresentation::nonlinear_srgb_to_lch([0.70, 0.19, 0.90]);
|
||||
assert_eq!((lightness * 100.0).round() as u32, 49);
|
||||
assert_eq!((chroma * 100.0).round() as u32, 100);
|
||||
assert_eq!(hue.round() as u32, 319);
|
||||
|
||||
// a green
|
||||
let (lightness, chroma, hue) = LchRepresentation::nonlinear_srgb_to_lch([0.10, 0.80, 0.59]);
|
||||
assert_eq!((lightness * 100.0).round() as u32, 73);
|
||||
assert_eq!((chroma * 100.0).round() as u32, 56);
|
||||
assert_eq!(hue.round() as u32, 164);
|
||||
|
||||
// a blue
|
||||
let (lightness, chroma, hue) = LchRepresentation::nonlinear_srgb_to_lch([0.25, 0.10, 0.92]);
|
||||
assert_eq!((lightness * 100.0).round() as u32, 34);
|
||||
assert_eq!((chroma * 100.0).round() as u32, 118);
|
||||
assert_eq!(hue.round() as u32, 307);
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,6 +44,17 @@ pub enum Color {
|
||||
/// Alpha channel. [0.0, 1.0]
|
||||
alpha: f32,
|
||||
},
|
||||
/// LCH(ab) (lightness, chroma, hue) color with an alpha channel
|
||||
Lcha {
|
||||
/// Lightness channel. [0.0, 1.5]
|
||||
lightness: f32,
|
||||
/// Chroma channel. [0.0, 1.5]
|
||||
chroma: f32,
|
||||
/// Hue channel. [0.0, 360.0]
|
||||
hue: f32,
|
||||
/// Alpha channel. [0.0, 1.0]
|
||||
alpha: f32,
|
||||
},
|
||||
}
|
||||
|
||||
impl Color {
|
||||
@ -401,7 +412,8 @@ impl Color {
|
||||
match self {
|
||||
Color::Rgba { alpha, .. }
|
||||
| Color::RgbaLinear { alpha, .. }
|
||||
| Color::Hsla { alpha, .. } => *alpha,
|
||||
| Color::Hsla { alpha, .. }
|
||||
| Color::Lcha { alpha, .. } => *alpha,
|
||||
}
|
||||
}
|
||||
|
||||
@ -410,7 +422,8 @@ impl Color {
|
||||
match self {
|
||||
Color::Rgba { alpha, .. }
|
||||
| Color::RgbaLinear { alpha, .. }
|
||||
| Color::Hsla { alpha, .. } => {
|
||||
| Color::Hsla { alpha, .. }
|
||||
| Color::Lcha { alpha, .. } => {
|
||||
*alpha = a;
|
||||
}
|
||||
}
|
||||
@ -454,6 +467,22 @@ impl Color {
|
||||
alpha: *alpha,
|
||||
}
|
||||
}
|
||||
Color::Lcha {
|
||||
lightness,
|
||||
chroma,
|
||||
hue,
|
||||
alpha,
|
||||
} => {
|
||||
let [red, green, blue] =
|
||||
LchRepresentation::lch_to_nonlinear_srgb(*lightness, *chroma, *hue);
|
||||
|
||||
Color::Rgba {
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
alpha: *alpha,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -487,6 +516,22 @@ impl Color {
|
||||
alpha: *alpha,
|
||||
}
|
||||
}
|
||||
Color::Lcha {
|
||||
lightness,
|
||||
chroma,
|
||||
hue,
|
||||
alpha,
|
||||
} => {
|
||||
let [red, green, blue] =
|
||||
LchRepresentation::lch_to_nonlinear_srgb(*lightness, *chroma, *hue);
|
||||
|
||||
Color::Rgba {
|
||||
red: red.nonlinear_to_linear_srgb(),
|
||||
green: green.nonlinear_to_linear_srgb(),
|
||||
blue: blue.nonlinear_to_linear_srgb(),
|
||||
alpha: *alpha,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -527,6 +572,22 @@ impl Color {
|
||||
}
|
||||
}
|
||||
Color::Hsla { .. } => *self,
|
||||
Color::Lcha {
|
||||
lightness,
|
||||
chroma,
|
||||
hue,
|
||||
alpha,
|
||||
} => {
|
||||
let rgb = LchRepresentation::lch_to_nonlinear_srgb(*lightness, *chroma, *hue);
|
||||
let (hue, saturation, lightness) = HslRepresentation::nonlinear_srgb_to_hsl(rgb);
|
||||
|
||||
Color::Hsla {
|
||||
hue,
|
||||
saturation,
|
||||
lightness,
|
||||
alpha: *alpha,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -560,6 +621,17 @@ impl Color {
|
||||
HslRepresentation::hsl_to_nonlinear_srgb(hue, saturation, lightness);
|
||||
[red, green, blue, alpha]
|
||||
}
|
||||
Color::Lcha {
|
||||
lightness,
|
||||
chroma,
|
||||
hue,
|
||||
alpha,
|
||||
} => {
|
||||
let [red, green, blue] =
|
||||
LchRepresentation::lch_to_nonlinear_srgb(lightness, chroma, hue);
|
||||
|
||||
[red, green, blue, alpha]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -599,6 +671,22 @@ impl Color {
|
||||
alpha,
|
||||
]
|
||||
}
|
||||
Color::Lcha {
|
||||
lightness,
|
||||
chroma,
|
||||
hue,
|
||||
alpha,
|
||||
} => {
|
||||
let [red, green, blue] =
|
||||
LchRepresentation::lch_to_nonlinear_srgb(lightness, chroma, hue);
|
||||
|
||||
[
|
||||
red.nonlinear_to_linear_srgb(),
|
||||
green.nonlinear_to_linear_srgb(),
|
||||
blue.nonlinear_to_linear_srgb(),
|
||||
alpha,
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -634,6 +722,63 @@ impl Color {
|
||||
lightness,
|
||||
alpha,
|
||||
} => [hue, saturation, lightness, alpha],
|
||||
Color::Lcha {
|
||||
lightness,
|
||||
chroma,
|
||||
hue,
|
||||
alpha,
|
||||
} => {
|
||||
let rgb = LchRepresentation::lch_to_nonlinear_srgb(lightness, chroma, hue);
|
||||
let (hue, saturation, lightness) = HslRepresentation::nonlinear_srgb_to_hsl(rgb);
|
||||
|
||||
[hue, saturation, lightness, alpha]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts a `Color` to a `[f32; 4]` from LCH colorspace
|
||||
pub fn as_lch_f32(self: Color) -> [f32; 4] {
|
||||
match self {
|
||||
Color::Rgba {
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
alpha,
|
||||
} => {
|
||||
let (lightness, chroma, hue) =
|
||||
LchRepresentation::nonlinear_srgb_to_lch([red, green, blue]);
|
||||
[lightness, chroma, hue, alpha]
|
||||
}
|
||||
Color::RgbaLinear {
|
||||
red,
|
||||
green,
|
||||
blue,
|
||||
alpha,
|
||||
} => {
|
||||
let (lightness, chroma, hue) = LchRepresentation::nonlinear_srgb_to_lch([
|
||||
red.linear_to_nonlinear_srgb(),
|
||||
green.linear_to_nonlinear_srgb(),
|
||||
blue.linear_to_nonlinear_srgb(),
|
||||
]);
|
||||
[lightness, chroma, hue, alpha]
|
||||
}
|
||||
Color::Hsla {
|
||||
hue,
|
||||
saturation,
|
||||
lightness,
|
||||
alpha,
|
||||
} => {
|
||||
let rgb = HslRepresentation::hsl_to_nonlinear_srgb(hue, saturation, lightness);
|
||||
let (lightness, chroma, hue) = LchRepresentation::nonlinear_srgb_to_lch(rgb);
|
||||
|
||||
[lightness, chroma, hue, alpha]
|
||||
}
|
||||
Color::Lcha {
|
||||
lightness,
|
||||
chroma,
|
||||
hue,
|
||||
alpha,
|
||||
} => [lightness, chroma, hue, alpha],
|
||||
}
|
||||
}
|
||||
|
||||
@ -680,6 +825,22 @@ impl Color {
|
||||
(alpha * 255.0) as u8,
|
||||
])
|
||||
}
|
||||
Color::Lcha {
|
||||
lightness,
|
||||
chroma,
|
||||
hue,
|
||||
alpha,
|
||||
} => {
|
||||
let [red, green, blue] =
|
||||
LchRepresentation::lch_to_nonlinear_srgb(lightness, chroma, hue);
|
||||
|
||||
u32::from_le_bytes([
|
||||
(red * 255.0) as u8,
|
||||
(green * 255.0) as u8,
|
||||
(blue * 255.0) as u8,
|
||||
(alpha * 255.0) as u8,
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -726,6 +887,22 @@ impl Color {
|
||||
(alpha * 255.0) as u8,
|
||||
])
|
||||
}
|
||||
Color::Lcha {
|
||||
lightness,
|
||||
chroma,
|
||||
hue,
|
||||
alpha,
|
||||
} => {
|
||||
let [red, green, blue] =
|
||||
LchRepresentation::lch_to_nonlinear_srgb(lightness, chroma, hue);
|
||||
|
||||
u32::from_le_bytes([
|
||||
(red.nonlinear_to_linear_srgb() * 255.0) as u8,
|
||||
(green.nonlinear_to_linear_srgb() * 255.0) as u8,
|
||||
(blue.nonlinear_to_linear_srgb() * 255.0) as u8,
|
||||
(alpha * 255.0) as u8,
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -775,6 +952,18 @@ impl AddAssign<Color> for Color {
|
||||
*lightness += rhs[2];
|
||||
*alpha += rhs[3];
|
||||
}
|
||||
Color::Lcha {
|
||||
lightness,
|
||||
chroma,
|
||||
hue,
|
||||
alpha,
|
||||
} => {
|
||||
let rhs = rhs.as_lch_f32();
|
||||
*lightness += rhs[0];
|
||||
*chroma += rhs[1];
|
||||
*hue += rhs[2];
|
||||
*alpha += rhs[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -826,6 +1015,21 @@ impl Add<Color> for Color {
|
||||
alpha: alpha + rhs[3],
|
||||
}
|
||||
}
|
||||
Color::Lcha {
|
||||
lightness,
|
||||
chroma,
|
||||
hue,
|
||||
alpha,
|
||||
} => {
|
||||
let rhs = rhs.as_lch_f32();
|
||||
|
||||
Color::Lcha {
|
||||
lightness: lightness + rhs[0],
|
||||
chroma: chroma + rhs[1],
|
||||
hue: hue + rhs[2],
|
||||
alpha: alpha + rhs[3],
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -936,6 +1140,17 @@ impl Mul<f32> for Color {
|
||||
lightness: lightness * rhs,
|
||||
alpha,
|
||||
},
|
||||
Color::Lcha {
|
||||
lightness,
|
||||
chroma,
|
||||
hue,
|
||||
alpha,
|
||||
} => Color::Lcha {
|
||||
lightness: lightness * rhs,
|
||||
chroma: chroma * rhs,
|
||||
hue: hue * rhs,
|
||||
alpha,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -963,6 +1178,16 @@ impl MulAssign<f32> for Color {
|
||||
*saturation *= rhs;
|
||||
*lightness *= rhs;
|
||||
}
|
||||
Color::Lcha {
|
||||
lightness,
|
||||
chroma,
|
||||
hue,
|
||||
..
|
||||
} => {
|
||||
*lightness *= rhs;
|
||||
*chroma *= rhs;
|
||||
*hue *= rhs;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1005,6 +1230,17 @@ impl Mul<Vec4> for Color {
|
||||
lightness: lightness * rhs.z,
|
||||
alpha: alpha * rhs.w,
|
||||
},
|
||||
Color::Lcha {
|
||||
lightness,
|
||||
chroma,
|
||||
hue,
|
||||
alpha,
|
||||
} => Color::Lcha {
|
||||
lightness: lightness * rhs.x,
|
||||
chroma: chroma * rhs.y,
|
||||
hue: hue * rhs.z,
|
||||
alpha: alpha * rhs.w,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1040,6 +1276,17 @@ impl MulAssign<Vec4> for Color {
|
||||
*lightness *= rhs.z;
|
||||
*alpha *= rhs.w;
|
||||
}
|
||||
Color::Lcha {
|
||||
lightness,
|
||||
chroma,
|
||||
hue,
|
||||
alpha,
|
||||
} => {
|
||||
*lightness *= rhs.x;
|
||||
*chroma *= rhs.y;
|
||||
*hue *= rhs.z;
|
||||
*alpha *= rhs.w;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1082,6 +1329,17 @@ impl Mul<Vec3> for Color {
|
||||
lightness: lightness * rhs.z,
|
||||
alpha,
|
||||
},
|
||||
Color::Lcha {
|
||||
lightness,
|
||||
chroma,
|
||||
hue,
|
||||
alpha,
|
||||
} => Color::Lcha {
|
||||
lightness: lightness * rhs.x,
|
||||
chroma: chroma * rhs.y,
|
||||
hue: hue * rhs.z,
|
||||
alpha,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1109,6 +1367,16 @@ impl MulAssign<Vec3> for Color {
|
||||
*saturation *= rhs.y;
|
||||
*lightness *= rhs.z;
|
||||
}
|
||||
Color::Lcha {
|
||||
lightness,
|
||||
chroma,
|
||||
hue,
|
||||
..
|
||||
} => {
|
||||
*lightness *= rhs.x;
|
||||
*chroma *= rhs.y;
|
||||
*hue *= rhs.z;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1151,6 +1419,17 @@ impl Mul<[f32; 4]> for Color {
|
||||
lightness: lightness * rhs[2],
|
||||
alpha: alpha * rhs[3],
|
||||
},
|
||||
Color::Lcha {
|
||||
lightness,
|
||||
chroma,
|
||||
hue,
|
||||
alpha,
|
||||
} => Color::Lcha {
|
||||
lightness: lightness * rhs[0],
|
||||
chroma: chroma * rhs[1],
|
||||
hue: hue * rhs[2],
|
||||
alpha: alpha * rhs[3],
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1186,6 +1465,17 @@ impl MulAssign<[f32; 4]> for Color {
|
||||
*lightness *= rhs[2];
|
||||
*alpha *= rhs[3];
|
||||
}
|
||||
Color::Lcha {
|
||||
lightness,
|
||||
chroma,
|
||||
hue,
|
||||
alpha,
|
||||
} => {
|
||||
*lightness *= rhs[0];
|
||||
*chroma *= rhs[1];
|
||||
*hue *= rhs[2];
|
||||
*alpha *= rhs[3];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1228,6 +1518,17 @@ impl Mul<[f32; 3]> for Color {
|
||||
lightness: lightness * rhs[2],
|
||||
alpha,
|
||||
},
|
||||
Color::Lcha {
|
||||
lightness,
|
||||
chroma,
|
||||
hue,
|
||||
alpha,
|
||||
} => Color::Lcha {
|
||||
lightness: lightness * rhs[0],
|
||||
chroma: chroma * rhs[1],
|
||||
hue: hue * rhs[2],
|
||||
alpha,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1255,6 +1556,16 @@ impl MulAssign<[f32; 3]> for Color {
|
||||
*saturation *= rhs[1];
|
||||
*lightness *= rhs[2];
|
||||
}
|
||||
Color::Lcha {
|
||||
lightness,
|
||||
chroma,
|
||||
hue,
|
||||
..
|
||||
} => {
|
||||
*lightness *= rhs[0];
|
||||
*chroma *= rhs[1];
|
||||
*hue *= rhs[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user