diff --git a/node-graph/gcore/src/color/color.rs b/node-graph/gcore/src/color/color.rs index 69edc39e87..69e97afa42 100644 --- a/node-graph/gcore/src/color/color.rs +++ b/node-graph/gcore/src/color/color.rs @@ -454,6 +454,28 @@ impl Color { Color { red, green, blue, alpha } } + /// Create a [Color] from given `f32` CMYKA channels (all between 0 and 1) + /// + /// # Examples + /// ``` + /// use graphene_core::color::Color; + /// let color = Color::from_cmyka(0.5, 0.2, 0.3, 0.5, 1.0); + /// ``` + // From https://graphicdesign.stackexchange.com/questions/114260/alternative-formulae-for-cmyk-to-rgb-conversion-for-display-on-screen + pub fn from_cmyka(cyan: f32, magenta: f32, yellow: f32, key: f32, alpha: f32) -> Color { + let cyan_temp: f32 = (1. - cyan) * 255.; + let magenta_temp: f32 = (1. - magenta) * 255.; + let yellow_temp: f32 = (1. - yellow) * 255.; + let red: f32 = (80. + 0.5882 * cyan_temp - 0.3529 * magenta_temp - 0.1373 * yellow_temp + 0.00185 * cyan_temp * magenta_temp + 0.00046 * yellow_temp * cyan_temp) / 255. * key; + let green: f32 = + (66. - 0.1961 * cyan_temp + 0.2745 * magenta_temp - 0.0627 * yellow_temp + 0.00215 * cyan_temp * magenta_temp + 0.00008 * yellow_temp * cyan_temp + 0.00062 * yellow_temp * magenta_temp) + / 255. * key; + let blue: f32 = + (86. - 0.3255 * cyan_temp - 0.1569 * magenta_temp + 0.1647 * yellow_temp + 0.00046 * cyan_temp * magenta_temp + 0.00123 * yellow_temp * cyan_temp + 0.00215 * yellow_temp * magenta_temp) + / 255. * key; + Color { red, green, blue, alpha } + } + /// Return the `red` component. /// /// # Examples diff --git a/node-graph/gmath-nodes/src/lib.rs b/node-graph/gmath-nodes/src/lib.rs index 37a7ed3644..0cd2201e0c 100644 --- a/node-graph/gmath-nodes/src/lib.rs +++ b/node-graph/gmath-nodes/src/lib.rs @@ -462,6 +462,36 @@ fn dot_product(_: impl Ctx, vector_a: DVec2, vector_b: DVec2) -> f64 { vector_a.dot(vector_b) } +/// Constructs a color from RGBA components. Clamped to 0 -> 1. +#[node_macro::node(category("Color"), name("RGBA to Color"))] +fn rgba_to_color(_: impl Ctx, _primary: (), red: f64, green: f64, blue: f64, alpha: f64) -> Color { + Color::from_rgbaf32_unchecked(red.clamp(0., 1.) as f32, green.clamp(0., 1.) as f32, blue.clamp(0., 1.) as f32, alpha.clamp(0., 1.) as f32) +} + +/// Constructs a color from HSLA components. Clamped to 0 -> 1. +#[node_macro::node(category("Color"), name("HSLA to Color"))] +fn hsla_to_color(_: impl Ctx, _primary: (), hue: f64, saturation: f64, lightness: f64, alpha: f64) -> Color { + Color::from_hsla(hue.clamp(0.0, 1.0) as f32, saturation.clamp(0., 1.) as f32, lightness.clamp(0., 1.) as f32, alpha.clamp(0., 1.) as f32) +} + +/// Constructs a color from a single grayscale value. Clamped to 0 -> 1. +#[node_macro::node(category("Color"))] +fn gray_to_color(_: impl Ctx, _primary: (), luminance: f64) -> Color { + Color::from_luminance(luminance.clamp(0., 1.) as f32) +} + +/// Constructs a color from CMYKA components. Clamped to 0 -> 1. +#[node_macro::node(category("Color"), name("CMYKA to Color"))] +fn cmyka_to_color(_: impl Ctx, _primary: (), cyan: f64, magenta: f64, yellow: f64, key: f64, alpha: f64) -> Color { + Color::from_cmyka( + cyan.clamp(0., 1.) as f32, + magenta.clamp(0., 1.) as f32, + yellow.clamp(0., 1.) as f32, + key.clamp(0., 1.) as f32, + alpha.clamp(0., 1.) as f32, + ) +} + #[cfg(test)] mod test { use super::*;