diff --git a/crates/bevy_color/src/color_ops.rs b/crates/bevy_color/src/color_ops.rs index e37592bdd4dba..e731a6f33c5a7 100644 --- a/crates/bevy_color/src/color_ops.rs +++ b/crates/bevy_color/src/color_ops.rs @@ -42,6 +42,19 @@ pub trait Mix: Sized { } } +/// Trait for returning a grayscale color of a provided lightness. +pub trait Gray: Mix + Sized { + /// A pure black color. + const BLACK: Self; + /// A pure white color. + const WHITE: Self; + + /// Returns a grey color with the provided lightness from (0.0 - 1.0). 0 is black, 1 is white. + fn gray(lightness: f32) -> Self { + Self::BLACK.mix(&Self::WHITE, lightness) + } +} + /// Methods for manipulating alpha values. pub trait Alpha: Sized { /// Return a new version of this color with the given alpha value. @@ -112,6 +125,8 @@ pub(crate) fn lerp_hue(a: f32, b: f32, t: f32) -> f32 { #[cfg(test)] mod tests { + use std::fmt::Debug; + use super::*; use crate::{testing::assert_approx_eq, Hsla}; @@ -145,4 +160,25 @@ mod tests { assert_approx_eq!(lerp_hue(350., 10., 0.5), 0., 0.001); assert_approx_eq!(lerp_hue(350., 10., 0.75), 5., 0.001); } + + fn verify_gray() + where + Col: Gray + Debug + PartialEq, + { + assert_eq!(Col::gray(0.), Col::BLACK); + assert_eq!(Col::gray(1.), Col::WHITE); + } + + #[test] + fn test_gray() { + verify_gray::(); + verify_gray::(); + verify_gray::(); + verify_gray::(); + verify_gray::(); + verify_gray::(); + verify_gray::(); + verify_gray::(); + verify_gray::(); + } } diff --git a/crates/bevy_color/src/hsla.rs b/crates/bevy_color/src/hsla.rs index 66aface9b4408..1f49e4875941f 100644 --- a/crates/bevy_color/src/hsla.rs +++ b/crates/bevy_color/src/hsla.rs @@ -1,5 +1,5 @@ use crate::{ - Alpha, ColorToComponents, Hsva, Hue, Hwba, Lcha, LinearRgba, Luminance, Mix, Srgba, + Alpha, ColorToComponents, Gray, Hsva, Hue, Hwba, Lcha, LinearRgba, Luminance, Mix, Srgba, StandardColor, Xyza, }; use bevy_math::{Vec3, Vec4}; @@ -119,6 +119,11 @@ impl Mix for Hsla { } } +impl Gray for Hsla { + const BLACK: Self = Self::new(0., 0., 0., 1.); + const WHITE: Self = Self::new(0., 0., 1., 1.); +} + impl Alpha for Hsla { #[inline] fn with_alpha(&self, alpha: f32) -> Self { diff --git a/crates/bevy_color/src/hsva.rs b/crates/bevy_color/src/hsva.rs index a66ca4c43bc91..cf89ea1013976 100644 --- a/crates/bevy_color/src/hsva.rs +++ b/crates/bevy_color/src/hsva.rs @@ -1,5 +1,5 @@ use crate::{ - Alpha, ColorToComponents, Hue, Hwba, Lcha, LinearRgba, Mix, Srgba, StandardColor, Xyza, + Alpha, ColorToComponents, Gray, Hue, Hwba, Lcha, LinearRgba, Mix, Srgba, StandardColor, Xyza, }; use bevy_math::{Vec3, Vec4}; use bevy_reflect::prelude::*; @@ -89,6 +89,11 @@ impl Mix for Hsva { } } +impl Gray for Hsva { + const BLACK: Self = Self::new(0., 0., 0., 1.); + const WHITE: Self = Self::new(0., 0., 1., 1.); +} + impl Alpha for Hsva { #[inline] fn with_alpha(&self, alpha: f32) -> Self { diff --git a/crates/bevy_color/src/hwba.rs b/crates/bevy_color/src/hwba.rs index 0f6f9a6b568b1..094b363f5b6a5 100644 --- a/crates/bevy_color/src/hwba.rs +++ b/crates/bevy_color/src/hwba.rs @@ -2,7 +2,9 @@ //! in [_HWB - A More Intuitive Hue-Based Color Model_] by _Smith et al_. //! //! [_HWB - A More Intuitive Hue-Based Color Model_]: https://web.archive.org/web/20240226005220/http://alvyray.com/Papers/CG/HWB_JGTv208.pdf -use crate::{Alpha, ColorToComponents, Hue, Lcha, LinearRgba, Mix, Srgba, StandardColor, Xyza}; +use crate::{ + Alpha, ColorToComponents, Gray, Hue, Lcha, LinearRgba, Mix, Srgba, StandardColor, Xyza, +}; use bevy_math::{Vec3, Vec4}; use bevy_reflect::prelude::*; @@ -91,6 +93,11 @@ impl Mix for Hwba { } } +impl Gray for Hwba { + const BLACK: Self = Self::new(0., 0., 1., 1.); + const WHITE: Self = Self::new(0., 1., 0., 1.); +} + impl Alpha for Hwba { #[inline] fn with_alpha(&self, alpha: f32) -> Self { diff --git a/crates/bevy_color/src/laba.rs b/crates/bevy_color/src/laba.rs index 8e35336335370..35943aa3b903f 100644 --- a/crates/bevy_color/src/laba.rs +++ b/crates/bevy_color/src/laba.rs @@ -1,5 +1,5 @@ use crate::{ - impl_componentwise_vector_space, Alpha, ColorToComponents, Hsla, Hsva, Hwba, LinearRgba, + impl_componentwise_vector_space, Alpha, ColorToComponents, Gray, Hsla, Hsva, Hwba, LinearRgba, Luminance, Mix, Oklaba, Srgba, StandardColor, Xyza, }; use bevy_math::{Vec3, Vec4}; @@ -101,6 +101,11 @@ impl Mix for Laba { } } +impl Gray for Laba { + const BLACK: Self = Self::new(0., 0., 0., 1.); + const WHITE: Self = Self::new(1., 0., 0., 1.); +} + impl Alpha for Laba { #[inline] fn with_alpha(&self, alpha: f32) -> Self { diff --git a/crates/bevy_color/src/lcha.rs b/crates/bevy_color/src/lcha.rs index 4058ef4d4be63..ddb039f194862 100644 --- a/crates/bevy_color/src/lcha.rs +++ b/crates/bevy_color/src/lcha.rs @@ -1,5 +1,6 @@ use crate::{ - Alpha, ColorToComponents, Hue, Laba, LinearRgba, Luminance, Mix, Srgba, StandardColor, Xyza, + Alpha, ColorToComponents, Gray, Hue, Laba, LinearRgba, Luminance, Mix, Srgba, StandardColor, + Xyza, }; use bevy_math::{Vec3, Vec4}; use bevy_reflect::prelude::*; @@ -122,6 +123,11 @@ impl Mix for Lcha { } } +impl Gray for Lcha { + const BLACK: Self = Self::new(0.0, 0.0, 0.0000136603785, 1.0); + const WHITE: Self = Self::new(1.0, 0.0, 0.0000136603785, 1.0); +} + impl Alpha for Lcha { #[inline] fn with_alpha(&self, alpha: f32) -> Self { diff --git a/crates/bevy_color/src/linear_rgba.rs b/crates/bevy_color/src/linear_rgba.rs index 9306b8927b352..041c039d9abb0 100644 --- a/crates/bevy_color/src/linear_rgba.rs +++ b/crates/bevy_color/src/linear_rgba.rs @@ -1,6 +1,6 @@ use crate::{ color_difference::EuclideanDistance, impl_componentwise_vector_space, Alpha, ColorToComponents, - Luminance, Mix, StandardColor, + Gray, Luminance, Mix, StandardColor, }; use bevy_math::{Vec3, Vec4}; use bevy_reflect::prelude::*; @@ -121,18 +121,6 @@ impl LinearRgba { } } - /// Construct a new [`LinearRgba`] color with the same value for all channels and an alpha of 1.0. - /// - /// A value of 0.0 is black, and a value of 1.0 is white. - pub const fn gray(value: f32) -> Self { - Self { - red: value, - green: value, - blue: value, - alpha: 1.0, - } - } - /// Return a copy of this color with the red channel set to the given value. pub const fn with_red(self, red: f32) -> Self { Self { red, ..self } @@ -236,6 +224,11 @@ impl Mix for LinearRgba { } } +impl Gray for LinearRgba { + const BLACK: Self = Self::BLACK; + const WHITE: Self = Self::WHITE; +} + impl Alpha for LinearRgba { #[inline] fn with_alpha(&self, alpha: f32) -> Self { diff --git a/crates/bevy_color/src/oklaba.rs b/crates/bevy_color/src/oklaba.rs index 1f4785d070c02..ec725adbdf6ba 100644 --- a/crates/bevy_color/src/oklaba.rs +++ b/crates/bevy_color/src/oklaba.rs @@ -1,6 +1,6 @@ use crate::{ color_difference::EuclideanDistance, impl_componentwise_vector_space, Alpha, ColorToComponents, - Hsla, Hsva, Hwba, Lcha, LinearRgba, Luminance, Mix, Srgba, StandardColor, Xyza, + Gray, Hsla, Hsva, Hwba, Lcha, LinearRgba, Luminance, Mix, Srgba, StandardColor, Xyza, }; use bevy_math::{Vec3, Vec4}; use bevy_reflect::prelude::*; @@ -101,6 +101,11 @@ impl Mix for Oklaba { } } +impl Gray for Oklaba { + const BLACK: Self = Self::new(0., 0., 0., 1.); + const WHITE: Self = Self::new(1.0, 0.0, 0.000000059604645, 1.0); +} + impl Alpha for Oklaba { #[inline] fn with_alpha(&self, alpha: f32) -> Self { diff --git a/crates/bevy_color/src/oklcha.rs b/crates/bevy_color/src/oklcha.rs index 18e6f532887ff..72b178fdc972b 100644 --- a/crates/bevy_color/src/oklcha.rs +++ b/crates/bevy_color/src/oklcha.rs @@ -1,6 +1,6 @@ use crate::{ - color_difference::EuclideanDistance, Alpha, ColorToComponents, Hsla, Hsva, Hue, Hwba, Laba, - Lcha, LinearRgba, Luminance, Mix, Oklaba, Srgba, StandardColor, Xyza, + color_difference::EuclideanDistance, Alpha, ColorToComponents, Gray, Hsla, Hsva, Hue, Hwba, + Laba, Lcha, LinearRgba, Luminance, Mix, Oklaba, Srgba, StandardColor, Xyza, }; use bevy_math::{Vec3, Vec4}; use bevy_reflect::prelude::*; @@ -119,6 +119,11 @@ impl Mix for Oklcha { } } +impl Gray for Oklcha { + const BLACK: Self = Self::new(0., 0., 0., 1.); + const WHITE: Self = Self::new(1.0, 0.000000059604645, 90.0, 1.0); +} + impl Alpha for Oklcha { #[inline] fn with_alpha(&self, alpha: f32) -> Self { diff --git a/crates/bevy_color/src/srgba.rs b/crates/bevy_color/src/srgba.rs index 0a4411aa6bceb..9de33883af82d 100644 --- a/crates/bevy_color/src/srgba.rs +++ b/crates/bevy_color/src/srgba.rs @@ -1,6 +1,6 @@ use crate::color_difference::EuclideanDistance; use crate::{ - impl_componentwise_vector_space, Alpha, ColorToComponents, LinearRgba, Luminance, Mix, + impl_componentwise_vector_space, Alpha, ColorToComponents, Gray, LinearRgba, Luminance, Mix, StandardColor, Xyza, }; use bevy_math::{Vec3, Vec4}; @@ -314,6 +314,11 @@ impl EuclideanDistance for Srgba { } } +impl Gray for Srgba { + const BLACK: Self = Self::BLACK; + const WHITE: Self = Self::WHITE; +} + impl ColorToComponents for Srgba { fn to_f32_array(self) -> [f32; 4] { [self.red, self.green, self.blue, self.alpha] diff --git a/crates/bevy_color/src/xyza.rs b/crates/bevy_color/src/xyza.rs index 6929ca5ca5799..ea20a2ee72fe4 100644 --- a/crates/bevy_color/src/xyza.rs +++ b/crates/bevy_color/src/xyza.rs @@ -1,5 +1,5 @@ use crate::{ - impl_componentwise_vector_space, Alpha, ColorToComponents, LinearRgba, Luminance, Mix, + impl_componentwise_vector_space, Alpha, ColorToComponents, Gray, LinearRgba, Luminance, Mix, StandardColor, }; use bevy_math::{Vec3, Vec4}; @@ -144,6 +144,11 @@ impl Mix for Xyza { } } +impl Gray for Xyza { + const BLACK: Self = Self::new(0., 0., 0., 1.); + const WHITE: Self = Self::new(0.95047, 1.0, 1.08883, 1.0); +} + impl ColorToComponents for Xyza { fn to_f32_array(self) -> [f32; 4] { [self.x, self.y, self.z, self.alpha] diff --git a/crates/bevy_core_pipeline/src/bloom/mod.rs b/crates/bevy_core_pipeline/src/bloom/mod.rs index 1dc253c758461..4069fd2cfcd90 100644 --- a/crates/bevy_core_pipeline/src/bloom/mod.rs +++ b/crates/bevy_core_pipeline/src/bloom/mod.rs @@ -2,7 +2,7 @@ mod downsampling_pipeline; mod settings; mod upsampling_pipeline; -use bevy_color::LinearRgba; +use bevy_color::{Gray, LinearRgba}; pub use settings::{BloomCompositeMode, BloomPrefilterSettings, BloomSettings}; use crate::{