mirror of
https://github.com/storytold/effectcraft.git
synced 2026-11-12 21:32:52 +00:00
Hue, Lightness and Saturation go up to 1000 % and Grain Size down to 0 (it keeps its wider maximum, 100), After Effects' recorded valid ranges in the same units. Noise HLS Auto shares the controls and widens with them. Defaults and sliders are unchanged. The renderers need no change: hue wraps, lightness and saturation clamp per pixel after the noise is added, and Grain Size is floored at 0.1 px on the CPU and the GPU, so the new values cost the same and stay finite. The amounts were written as "percent" in keyframe text because their range was 0..100, and Grain Size would become "percent" at 0..100; UNITS rows keep the units they had.
This commit is contained in:
6 files changed
+55
-8
No files matched your search
@@ -746,10 +746,6 @@ mod tests {
|
||||
("ec.color.changecolor", "hueTransform", 3480),
|
||||
("ec.time.pixelmotionblur", "shutterAngle", 3481),
|
||||
("ec.time.pixelmotionblur", "shutterSamples", 3482),
|
||||
("ec.noise.noisehls", "hue", 3483),
|
||||
("ec.noise.noisehls", "lightness", 3483),
|
||||
("ec.noise.noisehls", "saturation", 3483),
|
||||
("ec.noise.noisehls", "grainSize", 3484),
|
||||
("ec.noise.fractal", "subSettings/subInfluence", 3485),
|
||||
("ec.noise.fractal", "subSettings/subScaling", 3486),
|
||||
("ec.distort.ccpowerpin", "expandTop", 3492),
|
||||
|
||||
@@ -766,10 +766,12 @@ pub fn specs() -> Vec<EffectSpec> {
|
||||
let hls_common = || {
|
||||
vec![
|
||||
p("noise", "Noise", Value::Enum(0), popup(&["Uniform", "Squared", "Grain"])),
|
||||
p("hue", "Hue", num(0.0), pct()),
|
||||
p("lightness", "Lightness", num(0.0), pct()),
|
||||
p("saturation", "Saturation", num(0.0), pct()),
|
||||
p("grainSize", "Grain Size", num(1.0), slider(0.1, 100.0, 0.5, 10.0, 2)),
|
||||
// After Effects' valid ranges (#3483, #3484): the amounts go to 1000 %, Grain Size
|
||||
// down to 0 (the renderer floors it at 0.1 px) and keeps its wider maximum.
|
||||
p("hue", "Hue", num(0.0), slider(0.0, 1000.0, 0.0, 100.0, 1)),
|
||||
p("lightness", "Lightness", num(0.0), slider(0.0, 1000.0, 0.0, 100.0, 1)),
|
||||
p("saturation", "Saturation", num(0.0), slider(0.0, 1000.0, 0.0, 100.0, 1)),
|
||||
p("grainSize", "Grain Size", num(1.0), slider(0.0, 100.0, 0.5, 10.0, 2)),
|
||||
]
|
||||
};
|
||||
let mut hls = hls_common();
|
||||
@@ -967,6 +969,28 @@ mod tests {
|
||||
assert_eq!(still.img, img);
|
||||
}
|
||||
|
||||
/// #3483, #3484: amounts above 100 % keep adding noise, and Grain Size 0 renders (floored at
|
||||
/// 0.1 px) with finite output, for both effects.
|
||||
#[test]
|
||||
fn noise_hls_takes_after_effects_ranges() {
|
||||
let mut img = Image::new(16, 16);
|
||||
for (i, p) in img.data.iter_mut().enumerate() {
|
||||
*p = premul([0.6, 0.3, (i % 7) as f32 / 7.0], 1.0);
|
||||
}
|
||||
for id in ["ec.noise.noisehls", "ec.noise.noisehlsauto"] {
|
||||
let at = |amount: f64, grain: f64| {
|
||||
let vals =
|
||||
[("noise", Value::Enum(2)), ("hue", num(amount)), ("lightness", num(amount)), ("saturation", num(amount)), ("grainSize", num(grain))];
|
||||
run(id, &vals, img.clone(), 0.0).img
|
||||
};
|
||||
let (low, high) = (at(100.0, 1.0), at(1000.0, 1.0));
|
||||
assert_ne!(low, high, "{id}");
|
||||
for out in [high, at(1000.0, 0.0)] {
|
||||
assert!(out.data.iter().flatten().all(|v| v.is_finite() && (0.0..=1.0).contains(v)), "{id}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_grain_keeps_flat_mean() {
|
||||
let out = run("ec.noise.addgrain", &[("tweaking/intensity", num(2.0)), ("application/blendingMode", Value::Enum(2))], gray(64, 64, 0.5), 0.0);
|
||||
|
||||
@@ -318,6 +318,15 @@ pub(crate) const UNITS: &[(&str, &str, &str)] = &[
|
||||
("ec.matte.rotobrush", "refineEdgeMatte/shiftEdge", "percent"),
|
||||
("ec.matte.rotobrush", "refineEdgeMatte/decontamination/increaseDecontaminationRadius", ""),
|
||||
("ec.matte.simplechoker", "chokeMatte", "pixels"),
|
||||
// Their ranges were 0..100 (#3483, #3484).
|
||||
("ec.noise.noisehls", "hue", "percent"),
|
||||
("ec.noise.noisehls", "lightness", "percent"),
|
||||
("ec.noise.noisehls", "saturation", "percent"),
|
||||
("ec.noise.noisehls", "grainSize", ""),
|
||||
("ec.noise.noisehlsauto", "hue", "percent"),
|
||||
("ec.noise.noisehlsauto", "lightness", "percent"),
|
||||
("ec.noise.noisehlsauto", "saturation", "percent"),
|
||||
("ec.noise.noisehlsauto", "grainSize", ""),
|
||||
("ec.noise.fractal", "transform/scale", "percent"),
|
||||
("ec.noise.fractal", "transform/scaleWidth", "percent"),
|
||||
("ec.noise.fractal", "transform/scaleHeight", "percent"),
|
||||
|
||||
@@ -41,6 +41,14 @@ const ROWS: &[(u32, &str, &str, f64, f64)] = &[
|
||||
(3491, "ec.color.levelsic", "alpha/alphaGamma", 0.0, 10.0),
|
||||
(3478, "ec.generate.fourcolor", "blend", 1.0, 10000.0),
|
||||
(3479, "ec.generate.fourcolor", "jitter", 0.0, 500.0),
|
||||
(3483, "ec.noise.noisehls", "hue", 0.0, 1000.0),
|
||||
(3483, "ec.noise.noisehls", "lightness", 0.0, 1000.0),
|
||||
(3483, "ec.noise.noisehls", "saturation", 0.0, 1000.0),
|
||||
(3484, "ec.noise.noisehls", "grainSize", 0.0, 100.0),
|
||||
(3483, "ec.noise.noisehlsauto", "hue", 0.0, 1000.0),
|
||||
(3483, "ec.noise.noisehlsauto", "lightness", 0.0, 1000.0),
|
||||
(3483, "ec.noise.noisehlsauto", "saturation", 0.0, 1000.0),
|
||||
(3484, "ec.noise.noisehlsauto", "grainSize", 0.0, 100.0),
|
||||
];
|
||||
|
||||
fn path(effect: &str, param: &str) -> String {
|
||||
|
||||
@@ -497,4 +497,12 @@ fn widened_effect_ranges_keep_their_keyframe_text_units() {
|
||||
let text = copy_props(&mut s, l, &["effects/#1/blend", "effects/#1/jitter"]);
|
||||
assert_eq!(unit_of(&text, "Blend"), "percent");
|
||||
assert_eq!(unit_of(&text, "Jitter"), "percent");
|
||||
for fx in ["ec.noise.noisehls", "ec.noise.noisehlsauto"] {
|
||||
let (mut s, l) = session();
|
||||
s.execute("effect.apply", json!({"layer": l.0, "effect": fx})).unwrap();
|
||||
let text = copy_props(&mut s, l, &["effects/#1/hue", "effects/#1/lightness", "effects/#1/saturation", "effects/#1/grainSize"]);
|
||||
for (name, unit) in [("Hue", "percent"), ("Lightness", "percent"), ("Saturation", "percent"), ("Grain Size", "")] {
|
||||
assert_eq!(unit_of(&text, name), unit, "{fx} {name}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -164,6 +164,8 @@ fn noise_alpha_and_hls() {
|
||||
effect_case("ec.noise.noisehls", &[("hue", n(30.0)), ("lightness", n(20.0)), ("saturation", n(40.0))]);
|
||||
effect_case("ec.noise.noisehls", &[("noise", e(1)), ("lightness", n(50.0)), ("noisePhase", n(200.0))]);
|
||||
effect_case("ec.noise.noisehls", &[("noise", e(2)), ("hue", n(60.0)), ("saturation", n(25.0)), ("grainSize", n(3.0))]);
|
||||
// #3483, #3484: the ends of After Effects' ranges.
|
||||
effect_case("ec.noise.noisehls", &[("noise", e(2)), ("hue", n(1000.0)), ("lightness", n(1000.0)), ("saturation", n(1000.0)), ("grainSize", n(0.0))]);
|
||||
effect_case("ec.noise.noisehlsauto", &[("noise", e(0)), ("hue", n(20.0)), ("lightness", n(30.0)), ("noiseAnimationSpeed", n(7.0))]);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user