mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 22:28:10 +08:00
Add the Channel Mixer node (#1142)
* Add the Channel Mixer node * Fix NodeIdentifier not found in Registry * Add radio toggle for red/green/blue --------- Co-authored-by: Dennis Kobert <dennis@kobert.dev>
This commit is contained in:
@@ -460,6 +460,73 @@ fn vibrance_node(color: Color, vibrance: f64) -> Color {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct ChannelMixerNode<Monochrome, MonochromeR, MonochromeG, MonochromeB, MonochromeC, RedR, RedG, RedB, RedC, GreenR, GreenG, GreenB, GreenC, BlueR, BlueG, BlueB, BlueC> {
|
||||
monochrome: Monochrome,
|
||||
monochrome_r: MonochromeR,
|
||||
monochrome_g: MonochromeG,
|
||||
monochrome_b: MonochromeB,
|
||||
monochrome_c: MonochromeC,
|
||||
red_r: RedR,
|
||||
red_g: RedG,
|
||||
red_b: RedB,
|
||||
red_c: RedC,
|
||||
green_r: GreenR,
|
||||
green_g: GreenG,
|
||||
green_b: GreenB,
|
||||
green_c: GreenC,
|
||||
blue_r: BlueR,
|
||||
blue_g: BlueG,
|
||||
blue_b: BlueB,
|
||||
blue_c: BlueC,
|
||||
}
|
||||
|
||||
#[node_macro::node_fn(ChannelMixerNode)]
|
||||
fn channel_mixer_node(
|
||||
color: Color,
|
||||
monochrome: bool,
|
||||
monochrome_r: f64,
|
||||
monochrome_g: f64,
|
||||
monochrome_b: f64,
|
||||
monochrome_c: f64,
|
||||
red_r: f64,
|
||||
red_g: f64,
|
||||
red_b: f64,
|
||||
red_c: f64,
|
||||
green_r: f64,
|
||||
green_g: f64,
|
||||
green_b: f64,
|
||||
green_c: f64,
|
||||
blue_r: f64,
|
||||
blue_g: f64,
|
||||
blue_b: f64,
|
||||
blue_c: f64,
|
||||
) -> Color {
|
||||
let color = color.to_gamma_srgb();
|
||||
|
||||
let (r, g, b, a) = color.components();
|
||||
|
||||
let color = if monochrome {
|
||||
let (monochrome_r, monochrome_g, monochrome_b, monochrome_c) = (monochrome_r as f32 / 100., monochrome_g as f32 / 100., monochrome_b as f32 / 100., monochrome_c as f32 / 100.);
|
||||
|
||||
let gray = (r * monochrome_r + g * monochrome_g + b * monochrome_b + monochrome_c).clamp(0., 1.);
|
||||
|
||||
Color::from_rgbaf32_unchecked(gray, gray, gray, a)
|
||||
} else {
|
||||
let (red_r, red_g, red_b, red_c) = (red_r as f32 / 100., red_g as f32 / 100., red_b as f32 / 100., red_c as f32 / 100.);
|
||||
let (green_r, green_g, green_b, green_c) = (green_r as f32 / 100., green_g as f32 / 100., green_b as f32 / 100., green_c as f32 / 100.);
|
||||
let (blue_r, blue_g, blue_b, blue_c) = (blue_r as f32 / 100., blue_g as f32 / 100., blue_b as f32 / 100., blue_c as f32 / 100.);
|
||||
|
||||
let red = (r * red_r + g * red_g + b * red_b + red_c).clamp(0., 1.);
|
||||
let green = (r * green_r + g * green_g + b * green_b + green_c).clamp(0., 1.);
|
||||
let blue = (r * blue_r + g * blue_g + b * blue_b + blue_c).clamp(0., 1.);
|
||||
|
||||
Color::from_rgbaf32_unchecked(red, green, blue, a)
|
||||
};
|
||||
|
||||
color.to_linear_srgb()
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct OpacityNode<O> {
|
||||
opacity_multiplier: O,
|
||||
|
||||
@@ -258,6 +258,10 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
|
||||
raster_node!(graphene_core::raster::InvertRGBNode, params: []),
|
||||
raster_node!(graphene_core::raster::ThresholdNode<_, _, _>, params: [f64, f64, LuminanceCalculation]),
|
||||
raster_node!(graphene_core::raster::VibranceNode<_>, params: [f64]),
|
||||
raster_node!(
|
||||
graphene_core::raster::ChannelMixerNode<_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _>,
|
||||
params: [bool, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64]
|
||||
),
|
||||
vec![(
|
||||
NodeIdentifier::new("graphene_core::raster::BrightnessContrastNode<_, _, _>"),
|
||||
|args| {
|
||||
@@ -483,7 +487,12 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
|
||||
];
|
||||
let mut map: HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstructor>> = HashMap::new();
|
||||
for (id, c, types) in node_types.into_iter().flatten() {
|
||||
map.entry(id).or_default().insert(types.clone(), c);
|
||||
// TODO: this is a hack to remove the newline from the node new_name
|
||||
// This occurs for the ChannelMixerNode presumably because of the long name.
|
||||
// This might be caused by the stringify! macro
|
||||
let new_name = id.name.replace('\n', " ");
|
||||
let nid = NodeIdentifier { name: Cow::Owned(new_name) };
|
||||
map.entry(nid).or_default().insert(types.clone(), c);
|
||||
}
|
||||
map
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user