mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-14 19:27:05 -04:00
Effects: CC Particle World / Systems II replace their layer with the particles
The particles were composited with the original layer by the Transfer Mode, so the solid an artist applies them to stayed visible. After Effects 2026 frames show no trace of it: SceneYard "Burnout matchstick" (a red rectangle around the flame), "Documentary Man Falling" (a black block over the light), "Task Preparation UI" (black solids under fireworks). The Transfer Mode now only sets how the particles meet each other. Mean abs error vs AE: Burnout matchstick 0.0191 -> 0.0130, Documentary Man Falling 0.1177 -> 0.0937 (Task Preparation also needs the next commit). (cherry picked from commit 3eb3b9958f9cd929dcf060865e604d42cc0f9337) (cherry picked from commit 729638710e63f4da10711fc5e6a1f7ddc42c37aa) (cherry picked from commit 083332116c936f1b4863f0bb390d0647f2b567a1)
This commit is contained in:
1 parent
8bcc456caa
commit
338421de36
1 file changed
+31
-13
+31
-13
@@ -1196,18 +1196,9 @@ fn particle_world_plan(ctx: &EffectCtx, b: &Buf) -> Option<SpritePlan> {
|
||||
/// The CC particle systems' sprites with their Transfer Mode (Composite, Screen, Add, Black
|
||||
/// Background).
|
||||
fn particle_sprites(sprites: Vec<Sprite>, mode: u32) -> SpritePlan {
|
||||
SpritePlan {
|
||||
sprites,
|
||||
tints: vec![],
|
||||
acc: if mode == 2 { Acc::Add } else { Acc::Over },
|
||||
post: Post::Combine(match mode {
|
||||
0 => 0,
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
3 => 5,
|
||||
_ => 0,
|
||||
}),
|
||||
}
|
||||
// The particles replace the layer (After Effects shows no trace of the source in any
|
||||
// Transfer Mode, which sets how the particles meet each other).
|
||||
SpritePlan { sprites, tints: vec![], acc: if mode == 2 { Acc::Add } else { Acc::Over }, post: Post::Replace }
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------ CC Particle Systems II
|
||||
@@ -1920,8 +1911,35 @@ mod tests {
|
||||
let blank = Image::new(48, 48);
|
||||
let y = mass_y(&a, &blank);
|
||||
assert!((0.0..24.0).contains(&y), "{y}");
|
||||
// The particles replace the layer: with none born it is empty.
|
||||
let none = run("ec.sim.ccparticlesystems2", &[("birthRate", num(0.0))], grey(20, 20), 1.0);
|
||||
assert_eq!(none, grey(20, 20));
|
||||
assert_eq!(none, Image::new(20, 20));
|
||||
}
|
||||
|
||||
/// CC Particle World and CC Particle Systems II replace their layer with the particles, in
|
||||
/// every Transfer Mode (which only sets how particles meet each other). SceneYard frames from
|
||||
/// After Effects 2026 show no trace of the source solid: "Task Preparation UI" (black solids
|
||||
/// under fireworks hid a white page), "Burnout matchstick" (a red rectangle around the
|
||||
/// flame), "Documentary Man Falling" (a black block over the light).
|
||||
#[test]
|
||||
fn cc_particles_replace_their_layer() {
|
||||
let red = || {
|
||||
let mut img = Image::new(48, 48);
|
||||
img.data.iter_mut().for_each(|p| *p = [0.7, 0.1, 0.1, 1.0]);
|
||||
img
|
||||
};
|
||||
for id in ["ec.sim.ccparticlesystems2", "ec.sim.ccparticleworld"] {
|
||||
for mode in 0..4 {
|
||||
let v = vec![("birthRate", num(3.0)), ("particle/transferMode", Value::Enum(mode))];
|
||||
let _ = run(id, &v, red(), 0.5);
|
||||
let out = run(id, &v, red(), 1.0);
|
||||
// No source left: the corners, far from the producer, are clear.
|
||||
for (x, y) in [(0, 0), (47, 0), (0, 47), (47, 47)] {
|
||||
assert!(out.get(x, y)[3] < 1e-6, "{id} mode {mode} ({x},{y}): {:?}", out.get(x, y));
|
||||
}
|
||||
assert!(out.data.iter().any(|p| p[3] > 0.05), "{id} mode {mode}: particles drawn");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in new issue
Block a user