Echo, Posterize Time and the other Time effects read the layer at other times with none of
its effects. After Effects renders them with the effects before them: SceneYard "Task
Preparation UI" applies Echo after CC Particle Systems II on black solids, and AE shows the
echoed fireworks over a white page where we echoed the black solids and blacked it out
(Posterize Time after Turbulent Displace, the usual stop-motion setup, depends on the same).
The host already bounds the count to the effects before the one rendering.
Mean abs error vs AE: Task Preparation UI 0.1855 -> 0.0071, Lightbulb Idea 0.0126 -> 0.0102;
the 15 other corpus projects with a Time effect after another effect are pixel-identical.
(cherry picked from commit 46870452db2656c72406f63245e8b1609ceb04d4)
(cherry picked from commit 334d102582e5a64db32e2f3e55836d55ac96bdaa)
(cherry picked from commit 734da3e35dc57c01b73823458bdd87611ac1bf99)
(cherry picked from commit 87a733e076)
Time > Pixel Motion Blur fetched the layer at its shutter times and averaged the decoded
frames as they were, so fast motion rendered as doubled copies and the accepted Vector
Detail parameter changed nothing. Build a TimewarpPlan instead: every shutter instant is
decoded between the two source frames it falls between along a measured motion field — the
same block-matching and in-between synthesis Time > Timewarp uses, with a search radius
wide enough for full-frame displacements and the vector grid tightened from Vector Detail
0 (one vector per 32 px) to 100 (one per 2 px) — and the instants average into the blur.
CPU and GPU share the plan (fx_time renders it with its Timewarp step loop, declining to
the CPU when there is no host), so the existing GPU parity cases for the effect compare
the new path. Falling back to the old average is kept for layers without a time host.
A render integration test moves a textured block 12 px between source frames, renders
the straddling shutter, and asserts the output is neither the still nor the plain frame
overlay, lays trail coverage along the block's path, and changes with Vector Detail;
without the synthesis it fails at the overlay assertion.
GPU render passes for CC Particle World / Systems II, Particle Playground,
CC Ball Action, CC Pixel Polly, CC Scatterize and Curl Noise (fx_particles,
chunked multi-pass raster); Shatter wireframe views, Foam extras, Timewarp
with a Matte Layer, strong Warp Fisheye/Twist (CPU f64 inverse map) and
custom .ocio configs no longer fall back to the CPU. CPU refactors pinned by
particle_golden / timewarp_golden / sim_golden hashes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Timewarp without a Matte Layer is now planned once (time_fx::timewarp_plan: frames, shutter
instants, motion fields) and built by the CPU or the GPU from the plan; with a Matte Layer it
renders on the CPU (catalog::gpu_supported).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Lumetri: HSL Secondary key/refine/correction with Show Mask, Hue vs Sat/Hue/Luma,
Luma vs Sat, Sat vs Sat and per-channel RGB curves, High Dynamic Range (HDR White /
Specular), Input LUT and Look (custom .cube + built-in looks).
- Hue/Saturation: Channel Control with Reds..Magentas ranges (range + fall-offs).
- Levels: Channel popup and Red/Green/Blue/Alpha controls; Curves: Channel parameter.
- catalog::param_shown: Effect Controls shows only what a popup selects.
- Timewarp Pixel Motion: block-matching flow (raster::flow::block_flow_window) with
Vector Detail, Smoothing, Error Threshold, Block Size, Weighting, Correct Luminance,
Filtering, Build From One Image; Matte Layer/Channel, Warp Layer, Show, Source Crops.
- GPU falls back to CPU when channel/range controls are used.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
EffectHost gains self_at (the layer's source + masks + first N effects at
another layer time) and layer_at (another layer at another comp time);
EffectEnv carries the effect's stack index. The renderer serves these via
Renderer::layer_input, cached in the layer cache under input keys (footage
included, keyed by source time) with a depth guard against recursion.
Time effects are TIME_DEPENDENT so processed-layer keys fold in layer
time; layers with time effects and expressions are not cached.
Also registers the Effect > Audio specs (DSP in effects::audio_fx; the
mixdown integration follows in M11.2). Audio effects are skipped by the
video effect pass.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>