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