mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-31 07:38:24 +00:00
render: a 3D layer read outside its in/out range is transparent
solo_3d passed the layer to the 3D pipelines whatever the comp time, so an instance (CC Composite referencing a model layer) rendered before the source layer's in-point or after its out-point. Like any other layer reference, there is nothing to read outside the range: return the transparent canvas.
This commit is contained in:
1 parent
82cebba68f
commit
601a15bc1f
2 files changed
+28
-1
No files matched your search
@@ -155,3 +155,25 @@ fn instance3d_needs_a_3d_layer() {
|
||||
s.execute("layer.setSwitch", json!({"layers": [text], "switch": "threeD", "value": true})).unwrap();
|
||||
assert!(s.execute_checked("layer.create", json!({"op": "instance3d", "layers": [text]})).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn instance3d_shows_nothing_outside_the_source_layer_range() {
|
||||
let mut s = session();
|
||||
let model = triangle_model(&mut s);
|
||||
// The model's range ends at 1 s; the comp runs to 2 s.
|
||||
let comp = cid(&s);
|
||||
s.edit("trim", None, |p, _| {
|
||||
p.comp_mut(comp).unwrap().layer_mut(LayerId(model)).unwrap().out_point = Tick::from_seconds_f64(1.0);
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
s.execute("layer.select", json!({"layers": [model]})).unwrap();
|
||||
let r = s.execute("layer.create", json!({"op": "instance3d"})).unwrap();
|
||||
let _copy = r["layers"][0].as_u64().unwrap();
|
||||
// Inside the model's range the copy shows it, transparent around it.
|
||||
let inside = s.render(comp, Tick::from_seconds_f64(0.5), RenderOpts::default());
|
||||
assert!(px(&inside, 320, 180)[3] > 0.9, "the copy shows the model: {:?}", px(&inside, 320, 180));
|
||||
// After its out point the source has nothing to read: the copy is transparent.
|
||||
let outside = s.render(comp, Tick::from_seconds_f64(1.5), RenderOpts::default());
|
||||
assert!(outside.data.iter().all(|p| p[3] < 1e-3), "transparent after the source's out point: {:?}", px(&outside, 320, 180));
|
||||
}
|
||||
@@ -1510,12 +1510,17 @@ impl<'a> Renderer<'a> {
|
||||
let s = self.opts.scale;
|
||||
let w = ((ctx.comp.width as f64 * s).ceil() as u32).max(1);
|
||||
let h = ((ctx.comp.height as f64 * s).ceil() as u32).max(1);
|
||||
let mut canvas = Image::new(w, h);
|
||||
// Outside the layer's in/out points there is nothing to read: the copy is transparent
|
||||
// there, like any other layer reference (the 3D pipelines don't gate on the range).
|
||||
if !layer.is_active_at(ctx.time) {
|
||||
return Buf { img: canvas, offset: [0.0; 2], scale: s };
|
||||
}
|
||||
let mut solo = layer.clone();
|
||||
solo.track_matte = None;
|
||||
solo.blend_mode = effectcraft_color::BlendMode::Normal;
|
||||
solo.preserve_transparency = false;
|
||||
solo.switches.video = true;
|
||||
let mut canvas = Image::new(w, h);
|
||||
three_d::compose::draw_run(self, ctx, &[&solo], &mut canvas);
|
||||
Buf { img: canvas, offset: [0.0; 2], scale: s }
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user