Merge pull request #1111 from eliasx45/upstream/effect-fixes

This commit is contained in:
Brandon Thomas committed 2026-10-13 04:29:09 -04:00
commit 90621e2b04
5 files changed
+170 -133

No files matched your search

+2 -2
View File
@@ -354,8 +354,8 @@ pub trait EffectHost: Sync {
self.layer(id, false)
}
/// The effect's own layer at another **layer time** `layer_time` (seconds): its source with
/// masks applied, followed by the first `effects` effects of its stack (0 = none, which is
/// what After Effects' Time effects see). `None` when unavailable (no host, recursion
/// masks applied, followed by the first `effects` effects of its stack (0 = none; the host
/// never goes past the effect being rendered). `None` when unavailable (no host, recursion
/// limit, adjustment layers). Time effects use this to read neighbouring frames.
fn self_at(&self, _layer_time: f64, _effects: usize) -> Option<Buf> {
None
+31 -13
View File
@@ -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]
+9 -6
View File
@@ -1,10 +1,11 @@
//! Time effects (Effect > Time): Echo, Posterize Time, Time Difference, Time Displacement,
//! Timewarp, CC Force Motion Blur, CC Wide Time and Pixel Motion Blur.
//!
//! These read the layer at *other* layer times through [`EffectHost::self_at`] with zero
//! preceding effects: like After Effects' Time effects they see the layer's source with its
//! masks and ignore effects applied before them (precompose to include those). Without a host
//! (tests, thumbnails) they pass their input through.
//! These read the layer at *other* layer times through [`EffectHost::self_at`]: its source with
//! its masks and the effects applied before them, as After Effects renders them (SceneYard:
//! Echo after CC Particle Systems II echoes the fireworks, not the black solid under them;
//! Posterize Time after Turbulent Displace steps the displacement). Without a host (tests,
//! thumbnails) they pass their input through.
//!
//! Timewarp's Pixel Motion estimates block-matching optical flow between neighbouring frames
//! ([`effectcraft_raster::flow`]); Pixel Motion Blur averages sub-frame samples.
@@ -169,7 +170,8 @@ fn fetch(ctx: &EffectCtx, times: &[f64]) -> Option<Frames> {
let mut uniq: Vec<i64> = times.iter().map(|t| (t * 1e6).round() as i64).collect();
uniq.sort_unstable();
uniq.dedup();
let bufs: Vec<(i64, Option<Buf>)> = uniq.iter().map(|&k| (k, host.self_at(k as f64 / 1e6, 0))).collect();
// Every effect before this one (the host bounds the count to them).
let bufs: Vec<(i64, Option<Buf>)> = uniq.iter().map(|&k| (k, host.self_at(k as f64 / 1e6, usize::MAX))).collect();
let first = bufs.iter().find_map(|(_, b)| b.as_ref())?;
let scale = first.scale;
// Union of every frame's extent in layer pixels (offset = where layer (0,0) sits).
@@ -1014,7 +1016,8 @@ mod tests {
None
}
fn self_at(&self, t: f64, effects: usize) -> Option<Buf> {
assert_eq!(effects, 0);
// Time effects see every effect before them.
assert_eq!(effects, usize::MAX);
let v = if self.static_layer { 0.4 } else { t as f32 };
Some(Buf { img: Image::filled(6, 4, [v, v, v, 1.0]), offset: [0.0; 2], scale: 1.0 })
}
+112 -112
View File
@@ -334,34 +334,34 @@ fn particle_effects_golden_hashes() {
/// Pinned hashes (aarch64 macOS).
const GOLDEN: &[(&str, u64)] = &[
("ec.sim.ccparticleworld/0/8bpc/t0.5", 0x263d8f88e7ae651b),
("ec.sim.ccparticleworld/0/8bpc/t1.5", 0xb7697683e3cc6d43),
("ec.sim.ccparticleworld/0/8bpc/t0.8", 0xb5065326c8bd674a),
("ec.sim.ccparticleworld/0/8bpc/t2.2", 0x7f8eb5f2e8d38506),
("ec.sim.ccparticleworld/0/32bpc/t0.5", 0x6141abad89cd53ca),
("ec.sim.ccparticleworld/0/32bpc/t1.5", 0x2b5682e32bb3e916),
("ec.sim.ccparticleworld/0/32bpc/t0.8", 0xe6aaed9716d15c42),
("ec.sim.ccparticleworld/0/32bpc/t2.2", 0xa6e9a6f2acad94c0),
("ec.sim.ccparticleworld/0/8bpc/half/t0.5", 0xbb0b6803512a6b99),
("ec.sim.ccparticleworld/0/8bpc/half/t1.5", 0x70c578ea73992099),
("ec.sim.ccparticleworld/0/8bpc/half/t0.8", 0x2d26cb3f73a26b4f),
("ec.sim.ccparticleworld/0/8bpc/half/t2.2", 0x2b474438a48ee0e4),
("ec.sim.ccparticleworld/1/8bpc/t0.5", 0x294502dc827b0326),
("ec.sim.ccparticleworld/1/8bpc/t1.5", 0xf7874709f4012aaa),
("ec.sim.ccparticleworld/1/8bpc/t0.8", 0x87664ce9a05e67f9),
("ec.sim.ccparticleworld/1/8bpc/t2.2", 0x46e1b5162a0284f4),
("ec.sim.ccparticleworld/1/32bpc/t0.5", 0x02d8499e93133cb9),
("ec.sim.ccparticleworld/1/32bpc/t1.5", 0x97218172dec765c6),
("ec.sim.ccparticleworld/1/32bpc/t0.8", 0xee7da06e0b16e3b7),
("ec.sim.ccparticleworld/1/32bpc/t2.2", 0x6b9da0aa7d2a6abb),
("ec.sim.ccparticleworld/2/8bpc/t0.5", 0x71468ce82bba3cb2),
("ec.sim.ccparticleworld/2/8bpc/t1.5", 0x48595f55e8741a7e),
("ec.sim.ccparticleworld/2/8bpc/t0.8", 0x5ebc35e9eb02c8d7),
("ec.sim.ccparticleworld/2/8bpc/t2.2", 0xf9a0f63c72bd35f0),
("ec.sim.ccparticleworld/2/32bpc/t0.5", 0x757f80d45a2159b1),
("ec.sim.ccparticleworld/2/32bpc/t1.5", 0x7924f1cb9c8bf8c7),
("ec.sim.ccparticleworld/2/32bpc/t0.8", 0x22f507420a062c87),
("ec.sim.ccparticleworld/2/32bpc/t2.2", 0x41171121719a307a),
("ec.sim.ccparticleworld/0/8bpc/t0.5", 0x4444ad969d8a228e),
("ec.sim.ccparticleworld/0/8bpc/t1.5", 0xcad2aad73a6d603e),
("ec.sim.ccparticleworld/0/8bpc/t0.8", 0x513b356b746dacd0),
("ec.sim.ccparticleworld/0/8bpc/t2.2", 0x6c1915f3f8282023),
("ec.sim.ccparticleworld/0/32bpc/t0.5", 0x41943ef09dec3b46),
("ec.sim.ccparticleworld/0/32bpc/t1.5", 0x9f90b72b4f674214),
("ec.sim.ccparticleworld/0/32bpc/t0.8", 0xecd3343277ff0ea8),
("ec.sim.ccparticleworld/0/32bpc/t2.2", 0x7aff8cf24f352f11),
("ec.sim.ccparticleworld/0/8bpc/half/t0.5", 0x80dc4ec079743731),
("ec.sim.ccparticleworld/0/8bpc/half/t1.5", 0x79b651a929d56eba),
("ec.sim.ccparticleworld/0/8bpc/half/t0.8", 0xc537e2eae2138c98),
("ec.sim.ccparticleworld/0/8bpc/half/t2.2", 0x6dec97915b8a85a0),
("ec.sim.ccparticleworld/1/8bpc/t0.5", 0xbe5fff3969b604b1),
("ec.sim.ccparticleworld/1/8bpc/t1.5", 0x0505795960f35d94),
("ec.sim.ccparticleworld/1/8bpc/t0.8", 0x7337a55ab762142d),
("ec.sim.ccparticleworld/1/8bpc/t2.2", 0x82e9d79c843b8f73),
("ec.sim.ccparticleworld/1/32bpc/t0.5", 0x85e6f2dfa2cc2342),
("ec.sim.ccparticleworld/1/32bpc/t1.5", 0x3fc16468de930ff4),
("ec.sim.ccparticleworld/1/32bpc/t0.8", 0x0c8eede3cae44849),
("ec.sim.ccparticleworld/1/32bpc/t2.2", 0xabbc670cfdf0bedf),
("ec.sim.ccparticleworld/2/8bpc/t0.5", 0x5dd6f8961dc8aa01),
("ec.sim.ccparticleworld/2/8bpc/t1.5", 0x6632451f98c2bb66),
("ec.sim.ccparticleworld/2/8bpc/t0.8", 0x9c9840445d995203),
("ec.sim.ccparticleworld/2/8bpc/t2.2", 0xaa29bed036be7d9d),
("ec.sim.ccparticleworld/2/32bpc/t0.5", 0x7507310c57e5bc42),
("ec.sim.ccparticleworld/2/32bpc/t1.5", 0x6f0216e5fe64f20c),
("ec.sim.ccparticleworld/2/32bpc/t0.8", 0x0def6a02489d3bc7),
("ec.sim.ccparticleworld/2/32bpc/t2.2", 0xb0d1af988e47a2d5),
("ec.sim.ccparticleworld/3/8bpc/t0.5", 0xbca7e3d574cf5e37),
("ec.sim.ccparticleworld/3/8bpc/t1.5", 0x5c4347a6c70b48ec),
("ec.sim.ccparticleworld/3/8bpc/t0.8", 0xc79131dbaa8ff129),
@@ -370,74 +370,74 @@ const GOLDEN: &[(&str, u64)] = &[
("ec.sim.ccparticleworld/3/32bpc/t1.5", 0xf9751b9225a373a4),
("ec.sim.ccparticleworld/3/32bpc/t0.8", 0xb6026343f72dfaeb),
("ec.sim.ccparticleworld/3/32bpc/t2.2", 0x2f0e149de9623753),
("ec.sim.ccparticleworld/4/8bpc/t0.5", 0xd53dad7a75976197),
("ec.sim.ccparticleworld/4/8bpc/t1.5", 0x2cd0f3cbed038289),
("ec.sim.ccparticleworld/4/8bpc/t0.8", 0x46c089373ed50088),
("ec.sim.ccparticleworld/4/8bpc/t2.2", 0xfb17c5c3ba44657c),
("ec.sim.ccparticleworld/4/32bpc/t0.5", 0x80b338b7bb9794b1),
("ec.sim.ccparticleworld/4/32bpc/t1.5", 0x86811f65519e9790),
("ec.sim.ccparticleworld/4/32bpc/t0.8", 0x6aad5efc09bc64ff),
("ec.sim.ccparticleworld/4/32bpc/t2.2", 0x9957090d6fc97293),
("ec.sim.ccparticleworld/5/8bpc/t0.5", 0x56f989c5d7fc1eeb),
("ec.sim.ccparticleworld/5/8bpc/t1.5", 0x128313333a936e16),
("ec.sim.ccparticleworld/5/8bpc/t0.8", 0xa0efb8bdc0157788),
("ec.sim.ccparticleworld/5/8bpc/t2.2", 0x4af31455e2fe2631),
("ec.sim.ccparticleworld/5/32bpc/t0.5", 0xf3057d8cf6540f4a),
("ec.sim.ccparticleworld/5/32bpc/t1.5", 0x28203947d78e5ee3),
("ec.sim.ccparticleworld/5/32bpc/t0.8", 0xa6d8a9a848443344),
("ec.sim.ccparticleworld/5/32bpc/t2.2", 0xade682a437a4cba1),
("ec.sim.ccparticleworld/6/8bpc/t0.5", 0xa65b30a36baee78a),
("ec.sim.ccparticleworld/6/8bpc/t1.5", 0xbf7e4675fec18c48),
("ec.sim.ccparticleworld/6/8bpc/t0.8", 0xf98c7d9af9d6c9e2),
("ec.sim.ccparticleworld/6/8bpc/t2.2", 0xdf090357b8e4f471),
("ec.sim.ccparticleworld/6/32bpc/t0.5", 0x1721a9f149c922de),
("ec.sim.ccparticleworld/6/32bpc/t1.5", 0xf378db3b55dff048),
("ec.sim.ccparticleworld/6/32bpc/t0.8", 0x72a5d8dc0ea744ad),
("ec.sim.ccparticleworld/6/32bpc/t2.2", 0xfbb8e14088bb51ef),
("ec.sim.ccparticleworld/7/8bpc/t0.5", 0xc56801146ef15811),
("ec.sim.ccparticleworld/7/8bpc/t1.5", 0x3ca9b694e5e55f82),
("ec.sim.ccparticleworld/7/8bpc/t0.8", 0x2d72c095e0be6f47),
("ec.sim.ccparticleworld/7/8bpc/t2.2", 0x135b14387e6ea480),
("ec.sim.ccparticleworld/7/32bpc/t0.5", 0xad79b2f2d63d0c45),
("ec.sim.ccparticleworld/7/32bpc/t1.5", 0x902c6b68c6ed615d),
("ec.sim.ccparticleworld/7/32bpc/t0.8", 0x45045d7931c23788),
("ec.sim.ccparticleworld/7/32bpc/t2.2", 0xd8f8883374a3784f),
("ec.sim.ccparticleworld/8/8bpc/t0.5", 0xb681fe6e20dccbf3),
("ec.sim.ccparticleworld/8/8bpc/t1.5", 0xfa78174cb4fa5cd4),
("ec.sim.ccparticleworld/8/8bpc/t0.8", 0xd4f486333d843f09),
("ec.sim.ccparticleworld/8/8bpc/t2.2", 0xbee37590ce17b8b4),
("ec.sim.ccparticleworld/8/32bpc/t0.5", 0xccf4339bc42c3c01),
("ec.sim.ccparticleworld/8/32bpc/t1.5", 0xc51a8ee4e3c4a826),
("ec.sim.ccparticleworld/8/32bpc/t0.8", 0xee3d66e0c4ffb0ec),
("ec.sim.ccparticleworld/8/32bpc/t2.2", 0x449fc6d506e837fb),
("ec.sim.ccparticlesystems2/0/8bpc/t0.5", 0x3edb24bfeab4b00a),
("ec.sim.ccparticlesystems2/0/8bpc/t1.5", 0x78cb639f211cbd5b),
("ec.sim.ccparticlesystems2/0/8bpc/t0.8", 0x634c71924e4c68f1),
("ec.sim.ccparticlesystems2/0/8bpc/t2.2", 0xe09d41dcb6286423),
("ec.sim.ccparticlesystems2/0/32bpc/t0.5", 0xacdb6aec643a9bba),
("ec.sim.ccparticlesystems2/0/32bpc/t1.5", 0x4c50991034336999),
("ec.sim.ccparticlesystems2/0/32bpc/t0.8", 0xaacc2ea722f2e9e3),
("ec.sim.ccparticlesystems2/0/32bpc/t2.2", 0x1a5f7fc66db90a83),
("ec.sim.ccparticlesystems2/0/8bpc/half/t0.5", 0x8c89f83a2829dba1),
("ec.sim.ccparticlesystems2/0/8bpc/half/t1.5", 0x9239cd8895757d17),
("ec.sim.ccparticlesystems2/0/8bpc/half/t0.8", 0x91a16fb0a382d8e1),
("ec.sim.ccparticlesystems2/0/8bpc/half/t2.2", 0xc86d8250fe1402c5),
("ec.sim.ccparticlesystems2/1/8bpc/t0.5", 0xabade8d131837f05),
("ec.sim.ccparticlesystems2/1/8bpc/t1.5", 0x6a3566257b9a0bad),
("ec.sim.ccparticlesystems2/1/8bpc/t0.8", 0xc1199f209bad5c33),
("ec.sim.ccparticlesystems2/1/8bpc/t2.2", 0xaf337959d8264a5f),
("ec.sim.ccparticlesystems2/1/32bpc/t0.5", 0xb1816c2e5562be88),
("ec.sim.ccparticlesystems2/1/32bpc/t1.5", 0x02413f0ec8284e39),
("ec.sim.ccparticlesystems2/1/32bpc/t0.8", 0xd9bc645b90055a9a),
("ec.sim.ccparticlesystems2/1/32bpc/t2.2", 0x2c788bb5816167a3),
("ec.sim.ccparticlesystems2/2/8bpc/t0.5", 0xe18fd350f7155fc8),
("ec.sim.ccparticlesystems2/2/8bpc/t1.5", 0x956e03e2c83c3899),
("ec.sim.ccparticlesystems2/2/8bpc/t0.8", 0x7d16738562170622),
("ec.sim.ccparticlesystems2/2/8bpc/t2.2", 0x4e5838737bda7317),
("ec.sim.ccparticlesystems2/2/32bpc/t0.5", 0x27d909b24d165f6c),
("ec.sim.ccparticlesystems2/2/32bpc/t1.5", 0x47fb5492c0bcb748),
("ec.sim.ccparticlesystems2/2/32bpc/t0.8", 0x7dd63be8a11f4d71),
("ec.sim.ccparticlesystems2/2/32bpc/t2.2", 0x139259fc5f942375),
("ec.sim.ccparticleworld/4/8bpc/t0.5", 0xdfd4cff821add47f),
("ec.sim.ccparticleworld/4/8bpc/t1.5", 0x4ed5d9c97c8b323e),
("ec.sim.ccparticleworld/4/8bpc/t0.8", 0x13c8b1929529a4b1),
("ec.sim.ccparticleworld/4/8bpc/t2.2", 0xd9702ad6bbd34752),
("ec.sim.ccparticleworld/4/32bpc/t0.5", 0xabb4834618b86cb8),
("ec.sim.ccparticleworld/4/32bpc/t1.5", 0x54de0787c35112ff),
("ec.sim.ccparticleworld/4/32bpc/t0.8", 0xfe9ed5ed6c1fd8bd),
("ec.sim.ccparticleworld/4/32bpc/t2.2", 0x8278e2b011770e33),
("ec.sim.ccparticleworld/5/8bpc/t0.5", 0x11abba82d18e4540),
("ec.sim.ccparticleworld/5/8bpc/t1.5", 0x1be834f3d8d64464),
("ec.sim.ccparticleworld/5/8bpc/t0.8", 0xf3ad76cb0f38394d),
("ec.sim.ccparticleworld/5/8bpc/t2.2", 0x64e10ae00b8e48e5),
("ec.sim.ccparticleworld/5/32bpc/t0.5", 0xc5d6ad16b9b6f662),
("ec.sim.ccparticleworld/5/32bpc/t1.5", 0xcb7b7777e8ba0ea1),
("ec.sim.ccparticleworld/5/32bpc/t0.8", 0x09692a677eed64fc),
("ec.sim.ccparticleworld/5/32bpc/t2.2", 0x63e921f1dd7b52bc),
("ec.sim.ccparticleworld/6/8bpc/t0.5", 0xa954ad832566044b),
("ec.sim.ccparticleworld/6/8bpc/t1.5", 0x27fd580241299755),
("ec.sim.ccparticleworld/6/8bpc/t0.8", 0x8749025b3c953f71),
("ec.sim.ccparticleworld/6/8bpc/t2.2", 0xd01aff9a0712e02d),
("ec.sim.ccparticleworld/6/32bpc/t0.5", 0xd2213ab758ed6cb9),
("ec.sim.ccparticleworld/6/32bpc/t1.5", 0xa7287da977d06904),
("ec.sim.ccparticleworld/6/32bpc/t0.8", 0xd02d00dc0e651852),
("ec.sim.ccparticleworld/6/32bpc/t2.2", 0xc8930de7171f5ab3),
("ec.sim.ccparticleworld/7/8bpc/t0.5", 0x9166865a7c9ac035),
("ec.sim.ccparticleworld/7/8bpc/t1.5", 0x93901b6547233c1f),
("ec.sim.ccparticleworld/7/8bpc/t0.8", 0xe5d835162c42b6a5),
("ec.sim.ccparticleworld/7/8bpc/t2.2", 0xe81b1c734e88c7cb),
("ec.sim.ccparticleworld/7/32bpc/t0.5", 0x27924fd1804d9a61),
("ec.sim.ccparticleworld/7/32bpc/t1.5", 0x9daca8989bbd99f1),
("ec.sim.ccparticleworld/7/32bpc/t0.8", 0xcd2932f1ee19e946),
("ec.sim.ccparticleworld/7/32bpc/t2.2", 0x886af8fedcd62969),
("ec.sim.ccparticleworld/8/8bpc/t0.5", 0xe08dd245cbd88371),
("ec.sim.ccparticleworld/8/8bpc/t1.5", 0xcbe7b22563e912f4),
("ec.sim.ccparticleworld/8/8bpc/t0.8", 0x81bcded7ad281386),
("ec.sim.ccparticleworld/8/8bpc/t2.2", 0x5d176ad19ac06da2),
("ec.sim.ccparticleworld/8/32bpc/t0.5", 0x1dff22388b30e96d),
("ec.sim.ccparticleworld/8/32bpc/t1.5", 0x6f29f64ba5e160df),
("ec.sim.ccparticleworld/8/32bpc/t0.8", 0xfba8c8d708e417e4),
("ec.sim.ccparticleworld/8/32bpc/t2.2", 0xf3b2f2a1ea8c71d6),
("ec.sim.ccparticlesystems2/0/8bpc/t0.5", 0x01d2a42a3a56c69b),
("ec.sim.ccparticlesystems2/0/8bpc/t1.5", 0x953091e15d03438f),
("ec.sim.ccparticlesystems2/0/8bpc/t0.8", 0x668ea154b17b2eb0),
("ec.sim.ccparticlesystems2/0/8bpc/t2.2", 0x1862446b0c54b86c),
("ec.sim.ccparticlesystems2/0/32bpc/t0.5", 0xa1fb78a64db56ef3),
("ec.sim.ccparticlesystems2/0/32bpc/t1.5", 0x20ec7913584e6b71),
("ec.sim.ccparticlesystems2/0/32bpc/t0.8", 0xab390d348d0a66fd),
("ec.sim.ccparticlesystems2/0/32bpc/t2.2", 0x82f78af53a7c0096),
("ec.sim.ccparticlesystems2/0/8bpc/half/t0.5", 0xf7cf34b83bd3af18),
("ec.sim.ccparticlesystems2/0/8bpc/half/t1.5", 0x461020f3a3a4410d),
("ec.sim.ccparticlesystems2/0/8bpc/half/t0.8", 0xcd190eb7b38db0e8),
("ec.sim.ccparticlesystems2/0/8bpc/half/t2.2", 0x7f35000229186023),
("ec.sim.ccparticlesystems2/1/8bpc/t0.5", 0xf711d4d5244de44b),
("ec.sim.ccparticlesystems2/1/8bpc/t1.5", 0x61ea1dd478d0f90e),
("ec.sim.ccparticlesystems2/1/8bpc/t0.8", 0x1d23c2c8bb26577c),
("ec.sim.ccparticlesystems2/1/8bpc/t2.2", 0x0ca22baad9654c06),
("ec.sim.ccparticlesystems2/1/32bpc/t0.5", 0x6dc7b6570e174ee2),
("ec.sim.ccparticlesystems2/1/32bpc/t1.5", 0x491a30b9f0dac574),
("ec.sim.ccparticlesystems2/1/32bpc/t0.8", 0xfd9c7f0d0abd959e),
("ec.sim.ccparticlesystems2/1/32bpc/t2.2", 0x95ea630041185e8b),
("ec.sim.ccparticlesystems2/2/8bpc/t0.5", 0x165e69bf2a5f7a6a),
("ec.sim.ccparticlesystems2/2/8bpc/t1.5", 0xc5ce39b6beb3a4a1),
("ec.sim.ccparticlesystems2/2/8bpc/t0.8", 0x635bf9e56db3087d),
("ec.sim.ccparticlesystems2/2/8bpc/t2.2", 0x03bb626e929e6cdd),
("ec.sim.ccparticlesystems2/2/32bpc/t0.5", 0x92b5a331852e40fe),
("ec.sim.ccparticlesystems2/2/32bpc/t1.5", 0xae453b6fd4bbaeed),
("ec.sim.ccparticlesystems2/2/32bpc/t0.8", 0xfa4621a685214620),
("ec.sim.ccparticlesystems2/2/32bpc/t2.2", 0x84c180368e4411ad),
("ec.sim.ccparticlesystems2/3/8bpc/t0.5", 0xf14aad048c3b4181),
("ec.sim.ccparticlesystems2/3/8bpc/t1.5", 0xc261983ac6805eda),
("ec.sim.ccparticlesystems2/3/8bpc/t0.8", 0xf93ad1d6a9c493a5),
@@ -446,22 +446,22 @@ const GOLDEN: &[(&str, u64)] = &[
("ec.sim.ccparticlesystems2/3/32bpc/t1.5", 0x1c415c633baec738),
("ec.sim.ccparticlesystems2/3/32bpc/t0.8", 0x81a765f6e435e762),
("ec.sim.ccparticlesystems2/3/32bpc/t2.2", 0x7810e7f2ae55f619),
("ec.sim.ccparticlesystems2/4/8bpc/t0.5", 0xd246be64fea5db5f),
("ec.sim.ccparticlesystems2/4/8bpc/t1.5", 0x78ca37c0d19e87cf),
("ec.sim.ccparticlesystems2/4/8bpc/t0.8", 0xa5eacfbc0cc28a7c),
("ec.sim.ccparticlesystems2/4/8bpc/t2.2", 0xa527d1d2cdce5c96),
("ec.sim.ccparticlesystems2/4/32bpc/t0.5", 0x41c8b38886ae9652),
("ec.sim.ccparticlesystems2/4/32bpc/t1.5", 0x1e6d16247bb9c7a7),
("ec.sim.ccparticlesystems2/4/32bpc/t0.8", 0x05b125bdcd9a1794),
("ec.sim.ccparticlesystems2/4/32bpc/t2.2", 0x4752ed7777528cc8),
("ec.sim.ccparticlesystems2/5/8bpc/t0.5", 0x8ff7adb3b1720dbe),
("ec.sim.ccparticlesystems2/5/8bpc/t1.5", 0x2bb835296a78fccb),
("ec.sim.ccparticlesystems2/5/8bpc/t0.8", 0x674810581e32f80a),
("ec.sim.ccparticlesystems2/5/8bpc/t2.2", 0xecba1a3a740f4325),
("ec.sim.ccparticlesystems2/5/32bpc/t0.5", 0x30f53c7cb869066c),
("ec.sim.ccparticlesystems2/5/32bpc/t1.5", 0x1eb455f68b9decc8),
("ec.sim.ccparticlesystems2/5/32bpc/t0.8", 0xf396c8bdd516ef26),
("ec.sim.ccparticlesystems2/5/32bpc/t2.2", 0x7d0a6e30425ea5c3),
("ec.sim.ccparticlesystems2/4/8bpc/t0.5", 0x0106a8009fa18e2f),
("ec.sim.ccparticlesystems2/4/8bpc/t1.5", 0x5f12647281ea7ec9),
("ec.sim.ccparticlesystems2/4/8bpc/t0.8", 0x9f2655dbad770023),
("ec.sim.ccparticlesystems2/4/8bpc/t2.2", 0x44ca687ef817c0a1),
("ec.sim.ccparticlesystems2/4/32bpc/t0.5", 0x895b20656b6d3c98),
("ec.sim.ccparticlesystems2/4/32bpc/t1.5", 0x3a8b85da736ae6f0),
("ec.sim.ccparticlesystems2/4/32bpc/t0.8", 0x139f04a2dcf67d69),
("ec.sim.ccparticlesystems2/4/32bpc/t2.2", 0x02c844b7371128ac),
("ec.sim.ccparticlesystems2/5/8bpc/t0.5", 0x7b4a7112b6c8bb11),
("ec.sim.ccparticlesystems2/5/8bpc/t1.5", 0xf16ff18c451dbf63),
("ec.sim.ccparticlesystems2/5/8bpc/t0.8", 0xdedadbd43089dafe),
("ec.sim.ccparticlesystems2/5/8bpc/t2.2", 0x1e6fdb272dabf94c),
("ec.sim.ccparticlesystems2/5/32bpc/t0.5", 0xd17e5a60f476d0f7),
("ec.sim.ccparticlesystems2/5/32bpc/t1.5", 0xbfd43b69b45cd67c),
("ec.sim.ccparticlesystems2/5/32bpc/t0.8", 0x79fb89759eea8a6a),
("ec.sim.ccparticlesystems2/5/32bpc/t2.2", 0x0a70bc480c847d7e),
("ec.sim.particleplayground/0/8bpc/t0.5", 0x1842226399d43e19),
("ec.sim.particleplayground/0/8bpc/t1.5", 0xd5676389299c50e9),
("ec.sim.particleplayground/0/8bpc/t0.8", 0x30517e3b37e099d5),
+16
View File
@@ -64,6 +64,22 @@ fn echo_blends_neighbouring_frames() {
assert!((a - want).abs() < 0.01, "{a} vs {want}");
}
/// Time effects see the effects applied before them, as After Effects renders them (SceneYard
/// "Task Preparation UI": Echo after CC Particle Systems II echoed the black solid under the
/// fireworks and blacked out the white page). Fill (red) then Echo: the echoes are red.
#[test]
fn time_effects_see_the_effects_before_them() {
let (mut p, cid) = scene(Some(("ec.generate.fill", &[])));
let spec = effectcraft_effects::find("ec.time.echo").unwrap();
let mut next = p.next_id;
let mut g = effectcraft_effects::instantiate(spec, &mut Ids(&mut next), spec.name, [200.0, 100.0]);
g.prop_mut("numberOfEchoes").unwrap().value = Value::Scalar(0.0);
p.next_id = next;
p.comp_mut(cid).unwrap().layers[0].props.sub_mut("effects").unwrap().children.push(g.into());
let c = render(&p, cid, 1.5, None).get(100, 50);
assert!(c[0] > 0.99 && c[1] < 0.01 && c[2] < 0.01 && c[3] > 0.99, "{c:?}");
}
#[test]
fn time_difference_of_static_layer_is_black() {
let mut p = Project::default();