mirror of
https://github.com/storytold/filmcraft.git
synced 2026-10-14 11:17:01 -04:00
Merge pull request #1527 from marcoarnulfo/fix/adjustment-layer-transform-replaces-below
Adjustment layers: a Transform replaces the picture below instead of drawing over it
This commit is contained in:
commit
9418816580
2 files changed
+39
-6
No files matched your search
@@ -156,6 +156,26 @@ fn motion_and_masks_restrict_the_region() {
|
||||
assert!(near(img.get(280, 90), [1.0, 0.0, 0.0], 1e-4));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_transform_replaces_the_picture_below() {
|
||||
// Premiere: Transform on an adjustment layer moves the composite below; it is not a copy
|
||||
// drawn over the untouched original (#1524).
|
||||
let mut s = scene(2);
|
||||
let red = matte(&mut s.p, &mut s.map, [1.0, 0.0, 0.0, 1.0]);
|
||||
place(&mut s.p, s.seq, 0, red);
|
||||
let adj = adjustment(&mut s.p, s.seq, 1);
|
||||
fx(&mut s, adj, "transform");
|
||||
let tf = clip(&mut s, adj).effects.iter_mut().find(|e| e.effect == "transform").unwrap();
|
||||
tf.params.get_mut("scale_height").unwrap().value = ParamValue::Float(50.0);
|
||||
let img = render(&s);
|
||||
assert!(near(img.get(160, 90), [1.0, 0.0, 0.0], 1e-4), "{:?}", img.get(160, 90));
|
||||
assert_eq!(img.get(10, 10), [0.0; 4], "the original is gone outside the scaled picture");
|
||||
// at 50 % opacity: half the original, half the (empty) transformed picture
|
||||
clip(&mut s, adj).effect_mut("opacity").unwrap().params.get_mut("opacity").unwrap().value = ParamValue::Float(50.0);
|
||||
let c = render(&s).get(10, 10);
|
||||
assert!((c[0] - 0.5).abs() < 1e-3 && (c[3] - 0.5).abs() < 1e-3, "{c:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nested_adjustment_layers_stay_in_their_sequence() {
|
||||
let mut s = scene(2);
|
||||
|
||||
@@ -229,9 +229,14 @@ pub(crate) fn render_seq_tracks(project: &Project, seq: &Sequence, t: Tick, opts
|
||||
}
|
||||
let below = canvas.snapshot();
|
||||
let (adj, bl) = adjustment_layer(project, seq, item, t, opts, &tc, &below);
|
||||
let mut out = below;
|
||||
blend::composite(&mut out, &adj, 1.0, bl);
|
||||
canvas.set(out);
|
||||
if bl == Blend::Normal {
|
||||
// The adjusted picture already replaces the original (see `adjustment_layer`).
|
||||
canvas.set(adj);
|
||||
} else {
|
||||
let mut out = below;
|
||||
blend::composite(&mut out, &adj, 1.0, bl);
|
||||
canvas.set(out);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
match item_layer_ex(project, seq, item, t, opts, sources, &tc, true) {
|
||||
@@ -290,12 +295,20 @@ fn adjustment_layer(project: &Project, seq: &Sequence, item: &TrackItem, t: Tick
|
||||
mask::apply_effect(&mut adj, e, &cx);
|
||||
}
|
||||
let (op, bl) = opacity_blend(item, mt);
|
||||
// Adjustment layer opacity (and opacity masks, in sequence pixels) mix adjusted over original.
|
||||
adj.scale_alpha(op);
|
||||
mask::apply_opacity_masks(&mut adj, item, mt, opts.scale);
|
||||
// Adjustment layer opacity (and opacity masks, in sequence pixels) weigh adjusted against original.
|
||||
let mut weight = Image::filled(w, h, [op; 4]);
|
||||
mask::apply_opacity_masks(&mut weight, item, mt, opts.scale);
|
||||
// Motion moves / scales the adjustment layer's frame: it only applies inside it.
|
||||
if let Some(region) = adjustment_region(seq, item, project, mt, opts.scale, w, h) {
|
||||
let cov: Vec<f32> = region.px.as_chunks::<4>().0.iter().map(|p| p[3]).collect();
|
||||
mask::scale_by(&mut weight, &cov);
|
||||
}
|
||||
let cov: Vec<f32> = weight.px.as_chunks::<4>().0.iter().map(|p| p[3]).collect();
|
||||
if bl == Blend::Normal {
|
||||
// The adjusted picture replaces the original instead of being drawn over it: what
|
||||
// Transform or Basic 3D leave empty shows nothing of the untransformed picture (#1524).
|
||||
mask::mix(&mut adj, below, &cov);
|
||||
} else {
|
||||
mask::scale_by(&mut adj, &cov);
|
||||
}
|
||||
(adj, bl)
|
||||
|
||||
Reference in new issue
Block a user