Added a Grey trait to allow colors to create a generic "grey" color. This currently assumes the color spaces follow the same gradient, which I'm pretty sure isn't true, but it should make a "grey-ish" color relative to the provided intensity. # Objective - Implements #13206 ## Solution - A small `Grey` trait was added and implemented for the common color kinds. ## Testing - Currently untested, unit tests exposed the non-linear relation between colors. I am debating adding an example to show this, as I have no idea what color space represents what relation of grey, and I figure others may be similarly confused. ## Changelog - The `Grey` trait was added, and the corresponding `grey` ## BREAKING CHANGES The const qualifier for LinearRGBA::gray was removed (the symbol still exists via a trait, it's just not const anymore)
This commit is contained in:
parent
383314ef62
commit
1d29f8e6f6
@ -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.
|
/// Methods for manipulating alpha values.
|
||||||
pub trait Alpha: Sized {
|
pub trait Alpha: Sized {
|
||||||
/// Return a new version of this color with the given alpha value.
|
/// 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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{testing::assert_approx_eq, Hsla};
|
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.5), 0., 0.001);
|
||||||
assert_approx_eq!(lerp_hue(350., 10., 0.75), 5., 0.001);
|
assert_approx_eq!(lerp_hue(350., 10., 0.75), 5., 0.001);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn verify_gray<Col>()
|
||||||
|
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::<crate::Hsla>();
|
||||||
|
verify_gray::<crate::Hsva>();
|
||||||
|
verify_gray::<crate::Hwba>();
|
||||||
|
verify_gray::<crate::Laba>();
|
||||||
|
verify_gray::<crate::Lcha>();
|
||||||
|
verify_gray::<crate::LinearRgba>();
|
||||||
|
verify_gray::<crate::Oklaba>();
|
||||||
|
verify_gray::<crate::Oklcha>();
|
||||||
|
verify_gray::<crate::Xyza>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
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,
|
StandardColor, Xyza,
|
||||||
};
|
};
|
||||||
use bevy_math::{Vec3, Vec4};
|
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 {
|
impl Alpha for Hsla {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn with_alpha(&self, alpha: f32) -> Self {
|
fn with_alpha(&self, alpha: f32) -> Self {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
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_math::{Vec3, Vec4};
|
||||||
use bevy_reflect::prelude::*;
|
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 {
|
impl Alpha for Hsva {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn with_alpha(&self, alpha: f32) -> Self {
|
fn with_alpha(&self, alpha: f32) -> Self {
|
||||||
|
|||||||
@ -2,7 +2,9 @@
|
|||||||
//! in [_HWB - A More Intuitive Hue-Based Color Model_] by _Smith et al_.
|
//! 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
|
//! [_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_math::{Vec3, Vec4};
|
||||||
use bevy_reflect::prelude::*;
|
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 {
|
impl Alpha for Hwba {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn with_alpha(&self, alpha: f32) -> Self {
|
fn with_alpha(&self, alpha: f32) -> Self {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
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,
|
Luminance, Mix, Oklaba, Srgba, StandardColor, Xyza,
|
||||||
};
|
};
|
||||||
use bevy_math::{Vec3, Vec4};
|
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 {
|
impl Alpha for Laba {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn with_alpha(&self, alpha: f32) -> Self {
|
fn with_alpha(&self, alpha: f32) -> Self {
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
use crate::{
|
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_math::{Vec3, Vec4};
|
||||||
use bevy_reflect::prelude::*;
|
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 {
|
impl Alpha for Lcha {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn with_alpha(&self, alpha: f32) -> Self {
|
fn with_alpha(&self, alpha: f32) -> Self {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
color_difference::EuclideanDistance, impl_componentwise_vector_space, Alpha, ColorToComponents,
|
color_difference::EuclideanDistance, impl_componentwise_vector_space, Alpha, ColorToComponents,
|
||||||
Luminance, Mix, StandardColor,
|
Gray, Luminance, Mix, StandardColor,
|
||||||
};
|
};
|
||||||
use bevy_math::{Vec3, Vec4};
|
use bevy_math::{Vec3, Vec4};
|
||||||
use bevy_reflect::prelude::*;
|
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.
|
/// Return a copy of this color with the red channel set to the given value.
|
||||||
pub const fn with_red(self, red: f32) -> Self {
|
pub const fn with_red(self, red: f32) -> Self {
|
||||||
Self { red, ..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 {
|
impl Alpha for LinearRgba {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn with_alpha(&self, alpha: f32) -> Self {
|
fn with_alpha(&self, alpha: f32) -> Self {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
color_difference::EuclideanDistance, impl_componentwise_vector_space, Alpha, ColorToComponents,
|
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_math::{Vec3, Vec4};
|
||||||
use bevy_reflect::prelude::*;
|
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 {
|
impl Alpha for Oklaba {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn with_alpha(&self, alpha: f32) -> Self {
|
fn with_alpha(&self, alpha: f32) -> Self {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
color_difference::EuclideanDistance, Alpha, ColorToComponents, Hsla, Hsva, Hue, Hwba, Laba,
|
color_difference::EuclideanDistance, Alpha, ColorToComponents, Gray, Hsla, Hsva, Hue, Hwba,
|
||||||
Lcha, LinearRgba, Luminance, Mix, Oklaba, Srgba, StandardColor, Xyza,
|
Laba, Lcha, LinearRgba, Luminance, Mix, Oklaba, Srgba, StandardColor, Xyza,
|
||||||
};
|
};
|
||||||
use bevy_math::{Vec3, Vec4};
|
use bevy_math::{Vec3, Vec4};
|
||||||
use bevy_reflect::prelude::*;
|
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 {
|
impl Alpha for Oklcha {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn with_alpha(&self, alpha: f32) -> Self {
|
fn with_alpha(&self, alpha: f32) -> Self {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use crate::color_difference::EuclideanDistance;
|
use crate::color_difference::EuclideanDistance;
|
||||||
use crate::{
|
use crate::{
|
||||||
impl_componentwise_vector_space, Alpha, ColorToComponents, LinearRgba, Luminance, Mix,
|
impl_componentwise_vector_space, Alpha, ColorToComponents, Gray, LinearRgba, Luminance, Mix,
|
||||||
StandardColor, Xyza,
|
StandardColor, Xyza,
|
||||||
};
|
};
|
||||||
use bevy_math::{Vec3, Vec4};
|
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 {
|
impl ColorToComponents for Srgba {
|
||||||
fn to_f32_array(self) -> [f32; 4] {
|
fn to_f32_array(self) -> [f32; 4] {
|
||||||
[self.red, self.green, self.blue, self.alpha]
|
[self.red, self.green, self.blue, self.alpha]
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
impl_componentwise_vector_space, Alpha, ColorToComponents, LinearRgba, Luminance, Mix,
|
impl_componentwise_vector_space, Alpha, ColorToComponents, Gray, LinearRgba, Luminance, Mix,
|
||||||
StandardColor,
|
StandardColor,
|
||||||
};
|
};
|
||||||
use bevy_math::{Vec3, Vec4};
|
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 {
|
impl ColorToComponents for Xyza {
|
||||||
fn to_f32_array(self) -> [f32; 4] {
|
fn to_f32_array(self) -> [f32; 4] {
|
||||||
[self.x, self.y, self.z, self.alpha]
|
[self.x, self.y, self.z, self.alpha]
|
||||||
|
|||||||
@ -2,7 +2,7 @@ mod downsampling_pipeline;
|
|||||||
mod settings;
|
mod settings;
|
||||||
mod upsampling_pipeline;
|
mod upsampling_pipeline;
|
||||||
|
|
||||||
use bevy_color::LinearRgba;
|
use bevy_color::{Gray, LinearRgba};
|
||||||
pub use settings::{BloomCompositeMode, BloomPrefilterSettings, BloomSettings};
|
pub use settings::{BloomCompositeMode, BloomPrefilterSettings, BloomSettings};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user