Add a saturation input to the 'Vibrance' node and rework both axes to work in linear light (#4537)

* Add a saturation input to the 'Vibrance' node and rework both axes to work in linear light

* Refine the sliders

* Clarify some comments
This commit is contained in:
Keavon Chambers
2026-09-15 17:58:25 -07:00
committed by GitHub
parent 8d111e37f5
commit fac555ab3b
3 changed files with 129 additions and 92 deletions

View File

@@ -2095,18 +2095,16 @@ pub(crate) fn threshold_properties(node_id: NodeId, context: &mut NodeProperties
pub(crate) fn vibrance_properties(node_id: NodeId, context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
use graphene_std::raster::vibrance::*;
let track = Gradient::from(vec![Color::MIDDLE_GRAY, Color::RED]);
vec![spectrum_slider_row(
node_id,
context,
VibranceInput,
track,
Color::WHITE,
-100.,
100.,
0.,
NumberInput::default().mode_increment().unit("%").min(-100.).max(100.),
)]
let number_input = NumberInput::default().mode_increment().unit("%").min(-100.).max(100.);
let slider = SliderRange {
min: -100.,
max: 100.,
default: Some(0.),
};
let vibrance = range_slider_widget(ParameterWidgetsInfo::new(node_id, VibranceInput, true, context), number_input.clone(), slider);
let saturation = range_slider_widget(ParameterWidgetsInfo::new(node_id, SaturationInput, true, context), number_input, slider);
vec![LayoutGroup::row(vibrance), LayoutGroup::row(saturation)]
}
pub(crate) fn color_balance_properties(node_id: NodeId, context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {

View File

@@ -2196,6 +2196,17 @@ fn migrate_node(node_id: &NodeId, node: &DocumentNode, network_path: &[NodeId],
inputs_count = 3;
}
// Vibrance gained a Saturation input after its Vibrance input, whose default of 0 leaves old documents unchanged
if reference == DefinitionIdentifier::ProtoNode(graphene_std::raster::vibrance::IDENTIFIER) && inputs_count == 2 {
let mut node_template = resolve_document_node_type(&reference)?.default_node_template();
document.network_interface.replace_implementation(node_id, network_path, &mut node_template);
let old_inputs = document.network_interface.replace_inputs(node_id, network_path, &mut node_template)?;
for (index, input) in old_inputs.iter().take(2).enumerate() {
document.network_interface.set_input(&InputConnector::node_at_index(*node_id, index), input.clone(), network_path);
}
inputs_count = 3;
}
// Levels' Midtones became the gamma value it encoded, and each channel gained its own record after the composite one
if reference == DefinitionIdentifier::ProtoNode(graphene_std::raster::levels::IDENTIFIER) && inputs_count == 6 {
let mut node_template = resolve_document_node_type(&reference)?.default_node_template();