Add a gradient interpolation attribute with Stepped, Linear (existing), and Smooth modes (#4418)

* Delete dead code function

* Add a Gradient Interpolation axis with Stepped, Linear, and Smooth paths through the stops

* Keep the gradient interpolation attached when dragging stops in the picker

* Give the gradient popover's dropdowns the same tooltips as their row labels

* Order the gradient popover with Intrp. above Space

* Hold gradient stops in place when the cyclic flag is toggled

* Fix wrong Smooth gradient colors around stops sitting on the ramp boundaries

* Consolidate gradient settings plumbing and fix bugs

* Bundle whole-ramp gradient settings into GradientSettings across the editor plumbing

* Name the Smooth gradient interpolation's spline type in its tooltip

* Linearize the gamma hex stop colors recovered from imported Graphite SVGs

* Code review

* Aim the Smooth bake's seam subdivision at the copied boundary color

* Add GradientEvaluator to build gradient sampling state once per loop instead of per sample

* Correct the gradient evaluator's documented setup cost to O(n log n)
This commit is contained in:
Keavon Chambers
2026-08-07 16:43:36 -07:00
committed by Dennis Kobert
parent 244a7e0f78
commit 6e32e97ba1
24 changed files with 1552 additions and 750 deletions

View File

@@ -12,7 +12,8 @@ use rand::{Rng, SeedableRng};
use std::ops::{Add, Mul, Rem, Sub};
use vector_types::Gradient;
use vector_types::markers::{
GradientCyclic as GradientCyclicAttr, GradientForm as GradientFormAttr, GradientHueDirection as GradientHueDirectionAttr, GradientSpace as GradientSpaceAttr, GradientSpread as GradientSpreadAttr,
GradientCyclic as GradientCyclicAttr, GradientForm as GradientFormAttr, GradientHueDirection as GradientHueDirectionAttr, GradientInterpolation as GradientInterpolationAttr,
GradientSpace as GradientSpaceAttr, GradientSpread as GradientSpreadAttr,
};
/// The struct that stores the context for the maths parser.
@@ -1228,6 +1229,12 @@ fn gradient_hue_direction(_: impl Ctx, gradient: Gradient, gradient_hue_directio
(gradient, Attr(gradient_hue_direction))
}
/// Sets how the color progresses across each interval between gradient stops: stepped, linear, or smoothstep.
#[node_macro::node(category("Gradient"))]
fn gradient_interpolation(_: impl Ctx, gradient: Gradient, gradient_interpolation: vector_types::GradientInterpolation) -> (Gradient, Attr<GradientInterpolationAttr>) {
(gradient, Attr(gradient_interpolation))
}
/// Sets the position of each of a gradient's stops, a factor from 0 to 1 along the gradient.
///
/// A list shorter than the stop count repeats its last value, a longer list is truncated, and an empty list sets each stop to its default evenly spaced position.
@@ -1263,11 +1270,14 @@ fn sample_gradient(
return Err(GraphError::past_end().into());
}
let gradient_spread = gradient.lane(0).attr::<GradientSpreadAttr>();
let gradient_space = gradient.lane(0).attr::<GradientSpaceAttr>();
let gradient_hue_direction = gradient.lane(0).attr::<GradientHueDirectionAttr>();
let gradient_cyclic = gradient.lane(0).attr::<GradientCyclicAttr>();
Ok(gradient.element_ref(0).evaluate(position, gradient_spread, gradient_cyclic, gradient_space, gradient_hue_direction))
let settings = vector_types::GradientSettings {
spread: gradient.lane(0).attr::<GradientSpreadAttr>(),
cyclic: gradient.lane(0).attr::<GradientCyclicAttr>(),
space: gradient.lane(0).attr::<GradientSpaceAttr>(),
hue_direction: gradient.lane(0).attr::<GradientHueDirectionAttr>(),
interpolation: gradient.lane(0).attr::<GradientInterpolationAttr>(),
};
Ok(gradient.element_ref(0).evaluate(position, settings))
}
/// Constructs a footprint value which may be set to any transformation of a unit square describing a render area, and a render resolution at least 1x1 integer pixels.