Merge remote-tracking branch 'upstream/main' into rq-readback-3335

# Conflicts:
#	crates/render/src/lib.rs
This commit is contained in:
vangel76
2026-11-09 16:06:16 +01:00
105 changed files with 3208 additions and 987 deletions
+9 -1
View File
@@ -135,7 +135,15 @@ Units, the "absent = default" rule and the keyframe templates are the reader's
text does not have; the runs are cut to the text. A range style splits `Hello` into runs of 1,
2 and 2 characters (248, 340).
- **Null objects.** The hidden placeholder solid of a null object is not an item (null layers
have no source item here).
have no source item here). A null's Anchor Point that is not stored is its top-left corner
`[0, 0]`, not the centre, as After Effects 2026 reads it back (#3099).
- **Placed Illustrator and PDF files** (`.ai`, `.pdf`; `Footage::placed_page`): the page is
framed as After Effects places it (the ArtBox clipped to the crop box, `/Rotate` ignored) and
drawn to fill the stored footage size, which masks and anchors are measured against (#3099).
Create Shapes from Vector Layer on such a layer adds a hidden `<layer> Frame` shape layer, the
Alpha track matte of every layer it makes, so they show only the frame, as the footage does.
EPS files keep their bounding box at their own size: how After Effects sizes them is not
measured.
- **Track mattes.** The mode and the matte layer's id are in the target layer's header
(aep-format.md 3.1). The matte layer can be any layer of the composition (407: below its
target); it keeps its stored video switch (After Effects switches it off when the matte is set,
+14 -14
View File
@@ -43,7 +43,7 @@ cpal or muda. Everything in L0 to L4, the egui UI and the web app also build for
| L3 | `interchange` | Premiere Pro interop through timeline interchange (FCP7 XML, FCPXML, OTIO, EDL, AAF, OMF via FilmCraft's `filmcraft-interchange`): sequences ↔ compositions (§6a) |
| L3 | `aep` | After Effects projects in one crate (like `lottie`): `container` reads and writes the `.aep` container (RIFX `Egg!`) as a lossless chunk tree with a byte-identical round trip, bounded for hostile input, reads the `.aepx` XML form into the same tree, and has a typed view of items, layers, properties, effects, masks, shapes, text, markers, footage, cameras, lights and layer styles, from our own observations of generated files ([aep-format.md](aep-format.md)); `import` maps the typed view into a project (items, settings, compositions, every layer kind, Transform, keyframes, expressions, masks, text, shapes, cameras, lights, mattes, markers, time remapping, layer styles, the effects of a shared table, footage) with a report of everything not imported ([aep-import.md](aep-import.md)); `export` builds every chunk in code (prototypes in the layout After Effects writes, cloned and edited only at verified fields) for the same scope, with a report of everything not exported, verified by opening the output in After Effects ([aep-export.md](aep-export.md)) |
| L3 | `lottie` | Lottie JSON / dotLottie import and export (layers, precomps, eased and spatial keyframes, shapes, masks, mattes) with a warnings list for what Lottie cannot express |
| L3 | `plugin` | Effect plug-ins: loads sandboxed WebAssembly effect modules (plug-in API v1; the wasmi interpreter behind the `wasm` feature, on for native hosts) into the effect registry ([plugins.md](plugins.md)) |
| L3 | `plugin` | Effect plug-ins: loads sandboxed WebAssembly effect modules (WebAssembly ABI v1 and v2, the latter with neighbouring frames; the wasmi interpreter behind the `wasm` feature, on for native hosts) into the effect registry ([plugins.md](plugins.md)) |
| L3 | `helper-host` | External effect helpers: finds helper programs, runs each as a child process and registers its effects (plug-in API 2) over a versioned pipe + shared-file protocol; a crashing helper is an error on the effect, never a crash ([external-helpers.md](external-helpers.md), [ADR 0001](adr/0001-external-effect-helpers.md)). Native only |
| L4 | `engine` | `Session`: project, branching undo history, editor state, the command registry and menus, the ScriptUI window model (`scriptui`) |
| L4 | `script` | Scripting: JavaScript (boa) with an After Effects-style object model (`app.project`, comps, layers, properties, render queue) and ScriptUI (dialogs, palettes, dockable panels; script-host threads so dialogs block `show()`), whose edits run engine commands; AE match names |
@@ -121,7 +121,7 @@ are not rewritten, so an expression that computes an effect point on a shape or
other values may need `+ [thisComp.width / 2, thisComp.height / 2]`. Effects that use the layer
bounds (edge pinning, wipes, Offset, generators) now cover the whole comp-sized bounds instead of
their bottom-right quarter. Tracking data of effects that analyse footage (Warp Stabilizer, 3D
Camera Tracker, Mocha shape) is left as it is: footage has a source rectangle, whose effect space
Camera Tracker, Tracked Shape Matte) is left as it is: footage has a source rectangle, whose effect space
did not change.
## 4. Rendering
@@ -331,7 +331,7 @@ before conversion (a quarter of the conversions; the result differs from convert
in blocks where colours clip) and resampled from there, as other frames are from full size.
**GPU compositor** (`crates/gpu`; Project Settings ▸ Video Rendering and Effects ▸ Mercury GPU
Acceleration, the default, or Mercury Software Only; `render.backend`). The CPU renderer is the
Acceleration, the default, or Software Rendering; `render.backend`). The CPU renderer is the
reference and keeps rendering layer content (sources, masks, CPU effects, layer styles) into the
layer cache. The render crate defines an `Accelerator` trait; `effectcraft_gpu::Gpu` implements it
on wgpu compute shaders. `RenderOpts::backend` picks `Cpu`, `Gpu` or `Auto` (an accelerator
@@ -341,7 +341,7 @@ per comp, output scale and path (readback or viewer display) it averages CPU and
(warm-up on both sides, the fastest warm-up frame starting the average, single stalls capped),
picks the GPU unless the CPU is clearly faster, and re-measures the other side every 48 frames.
Render Queue jobs don't use Auto: every frame of a job renders on the project's renderer (the
GPU compositor with Mercury GPU Acceleration), so runs of a render don't differ by timing.
GPU compositor with GPU Acceleration), so runs of a render don't differ by timing.
Light comps (a few small layers, which the CPU composites only within their bounds) then stay on
the CPU instead of paying for full-frame passes and a readback. A GPU frame walks the comp like
`draw_comp`: cached layer buffers are uploaded once per buffer, then transformed with the CPU's
@@ -370,16 +370,16 @@ Preserve Transparency / blend kernels (a 3D track matte renders solo through the
Environment Light Background layers draw their sky in a kernel (`adv_sky`, from
`Renderer::sky_draw`) before the rest of the run, in Classic and Advanced 3D comps. Wireframe
outlines draw on the GPU from the CPU's pixel list (`Renderer::wireframe_pixels`). GPU effects
(`effects::GPU_EFFECTS`, 280 of them: blurs, colour correction, keying incl. Key Light, mattes,
channel, stylize, distortion and warps (Warp, Bezier Warp, Smear, Reshape, CC Bend It, CC Page
Turn, CC Bender, CC Blobbylize), Cartoon, bevels, shapes, the transitions (CC light family, CC
transitions, Block Dissolve), perspective (Radial Shadow, CC Cylinder / Sphere / Spotlight /
(`effects::GPU_EFFECTS`, 280 of them: blurs, colour correction, keying incl. Screen Color Key, mattes,
channel, stylize, distortion and warps (Warp, Bezier Warp, Smear, Reshape, Two-Point Bend, CC Page
Turn, Flexible Bend, Organic Displacement), Cartoon, bevels, shapes, the transitions (CC light family, CC
transitions, Block Dissolve), perspective (Radial Shadow, Cylinder Wrap / Sphere / Spotlight /
Environment, 3D Glasses), generators, noise, grain, text (Numbers, Timecode), time, 3D Channel (aux channels as an
extra texture), Immersive Video, colour management (colour programs from
`effects::color_program`, LUTs in a storage buffer) and the simulations' render passes (the
simulation stays on the CPU and hands its plan — sprites, pieces, blobs, grids — to a tiled
rasteriser; the particle effects too, `gpu::fx_particles`: CC Particle World / Systems II,
Particle Playground with its Layer Map frames in one atlas, CC Ball Action, CC Pixel Polly, CC
rasteriser; the particle effects too, `gpu::fx_particles`: Particle Emitter 3D / Systems II,
Particle Playground with its Layer Map frames in one atlas, Ball Grid, Pixel Shatter, CC
Scatterize; plans too large for one item table draw in several passes over the previous one),
and the geometry generators (Lightning, Advanced Lightning, Radio Waves, Stroke, Scribble,
Vegas, Write-on, Audio Spectrum / Waveform, Basic / Path Text: bolts, strokes, waves, audio
@@ -390,7 +390,7 @@ as kernels, in one module per family (`gpu::fx_*` with `shaders/fx_*.wgsl`); con
effects run as one chain with one upload and one readback. Statistics that need the whole frame
(Auto Levels / Contrast / Color, Equalize, Shadow/Highlight, Color Stabilizer, Remove Grain's
noise level) are measured on the CPU from one readback and applied on the GPU; effects reading
other frames (Echo, Posterize Time, Time Difference, Time Displacement, CC Force Motion Blur, CC
other frames (Echo, Posterize Time, Time Difference, Time Displacement, Temporal Motion Blur, CC
Wide Time, Pixel Motion Blur, Timewarp) upload the frames the host renders (`time_frames`) and
combine them on the GPU; Time Displacement's per-pixel times and Timewarp's motion vectors
(`time_fx::timewarp_plan`) are computed on the CPU. Numbers and Timecode rasterise their glyph
@@ -433,12 +433,12 @@ sentinel is implemented here. Browser scope futures are not synchronously awaite
forwards shared-device errors, while owned worker devices install their own handlers. On the web
(WebGPU) the GPU composites viewer frames; steps that need a readback fall back to the CPU (the
Info panel's pixel readout reads GPU frames back asynchronously). **GPU particles**
(`effects::psim`, `gpu::particles`): CC Particle World, CC Particle Systems II and Particle
(`effects::psim`, `gpu::particles`): Particle Emitter 3D, Particle Emitter 2D and Particle
Playground cannons without interacting forces evolve every particle independently, so the GPU
backend (reached through `EffectHost::particles` when the GPU compositor is active) simulates one
particle per invocation from the CPU's birth schedule and keeps per-key state checkpoints on the
GPU, like `SimCache`; the CPU simulation stays the oracle (tests compare ids and positions).
CC Particle World, CC Particle Systems II and CC Mr. Mercury sample their Birth Rate at every
Particle Emitter 3D, Particle Emitter 2D and Liquid Particles sample their Birth Rate at every
step (`EffectHost::param_at`, #1373), so a keyed rate only decides the births of its own time;
the rate is left out of the simulation key, and a checkpoint is resumed only with the same rate history (the CPU state's `hist`, the GPU
checkpoint's births). The rate's keyframes are read at the step's exact layer time
@@ -629,7 +629,7 @@ Unix milliseconds. The layer's Start Time becomes `dataStart + videoStart − fi
(`videoStart` given, or the file's creation date on the desktop; reduced to a time of day when
the data has no dates).
**Lumetri Scopes** (`raster::scopes`) are density plots of the viewer frame (rendered over the
**Video Scopes** (`raster::scopes`) are density plots of the viewer frame (rendered over the
comp background) with BT.601 / BT.709 / BT.2020 luma and colour-difference coefficients.
## 5. Expressions
+72 -72
View File
@@ -48,21 +48,21 @@ Effects are addressed by id (`ec.<category>.<name>`) or display name in commands
| Effect | Id | Params | GPU | 32 | Status |
|---|---|---:|:-:|:-:|---|
| Bilateral Blur | `ec.blur.bilateral` | 3 | GPU | 32 | Implemented |
| CC Cross Blur | `ec.blur.cccross` | 3 | GPU | 32 | Implemented |
| CC Radial Blur | `ec.blur.ccradial` | 4 | GPU | 32 | Implemented |
| CC Radial Fast Blur | `ec.blur.ccradialfast` | 3 | GPU | 32 | Implemented |
| CC Vector Blur | `ec.blur.ccvector` | 4 | GPU | 32 | Implemented |
| Camera Lens Blur | `ec.blur.cameralens` | 16 | GPU | 32 | Implemented |
| Camera-Shake Deblur | `ec.blur.camerashakedeblur` | 8 | | 32 | Implemented |
| Channel Blur | `ec.blur.channel` | 6 | GPU | 32 | Implemented |
| Compound Blur | `ec.blur.compound` | 4 | GPU | 32 | Implemented |
| Cross Blur | `ec.blur.cccross` | 3 | GPU | 32 | Implemented |
| Directional Blur | `ec.blur.directional` | 2 | GPU | 32 | Implemented |
| Fast Box Blur | `ec.blur.fastbox` | 4 | GPU | 32 | Implemented |
| Fast Radial Blur | `ec.blur.ccradialfast` | 3 | GPU | 32 | Implemented |
| Gaussian Blur | `ec.blur.gaussian` | 3 | GPU | 32 | Implemented |
| Radial Blur | `ec.blur.radial` | 4 | GPU | 32 | Implemented |
| Sharpen | `ec.blur.sharpen` | 1 | GPU | 32 | Implemented |
| Smart Blur | `ec.blur.smart` | 3 | GPU | 32 | Implemented |
| Unsharp Mask | `ec.blur.unsharp` | 3 | GPU | 32 | Implemented |
| Variable Radial Blur | `ec.blur.ccradial` | 4 | GPU | 32 | Implemented |
| Vector Blur | `ec.blur.ccvector` | 4 | GPU | 32 | Implemented |
## Channel
@@ -70,7 +70,6 @@ Effects are addressed by id (`ec.<category>.<name>`) or display name in commands
|---|---|---:|:-:|:-:|---|
| Arithmetic | `ec.channel.arithmetic` | 5 | GPU | 32 | Implemented |
| Blend | `ec.channel.blend` | 4 | GPU | 32 | Implemented |
| CC Composite | `ec.channel.cccomposite` | 3 | GPU | 32 | Implemented |
| Calculations | `ec.channel.calculations` | 9 | GPU | 32 | Implemented |
| Channel Combiner | `ec.channel.combiner` | 6 | GPU | 32 | Implemented |
| Compound Arithmetic | `ec.channel.compoundarithmetic` | 6 | GPU | 32 | Implemented |
@@ -81,6 +80,7 @@ Effects are addressed by id (`ec.<category>.<name>`) or display name in commands
| Set Matte | `ec.channel.setmatte` | 6 | GPU | 32 | Implemented |
| Shift Channels | `ec.channel.shiftchannels` | 4 | GPU | 32 | Implemented |
| Solid Composite | `ec.channel.solidcomposite` | 4 | GPU | 32 | Implemented |
| Source Composite | `ec.channel.cccomposite` | 3 | GPU | 32 | Implemented |
## Color Correction
@@ -92,18 +92,18 @@ Effects are addressed by id (`ec.<category>.<name>`) or display name in commands
| Black & White | `ec.color.blackwhite` | 8 | GPU | 32 | Implemented |
| Brightness & Contrast | `ec.color.brightnesscontrast` | 3 | GPU | 32 | Implemented |
| Broadcast Colors | `ec.color.broadcast` | 3 | GPU | 32 | Implemented |
| CC Color Neutralizer | `ec.color.cccolorneutralizer` | 11 | GPU | 32 | Implemented |
| CC Color Offset | `ec.color.cccoloroffset` | 4 | GPU | 32 | Implemented |
| CC Kernel | `ec.color.cckernel` | 12 | GPU | 32 | Implemented |
| CC Toner | `ec.color.cctoner` | 7 | GPU | 32 | Implemented |
| Change Color | `ec.color.changecolor` | 9 | GPU | 32 | Implemented |
| Change to Color | `ec.color.changetocolor` | 9 | GPU | 32 | Implemented |
| Channel Mixer | `ec.color.channelmixer` | 13 | GPU | 32 | Implemented |
| Channel Offset | `ec.color.cccoloroffset` | 4 | GPU | 32 | Implemented |
| Color Balance | `ec.color.colorbalance` | 10 | GPU | 32 | Implemented |
| Color Balance (HLS) | `ec.color.colorbalancehls` | 3 | GPU | 32 | Implemented |
| Color Grading | `ec.color.lumetri` | 66 | GPU | 32 | Implemented |
| Color Link | `ec.color.colorlink` | 6 | GPU | 32 | Implemented |
| Color Neutralizer | `ec.color.cccolorneutralizer` | 11 | GPU | 32 | Implemented |
| Color Stabilizer | `ec.color.colorstabilizer` | 6 | GPU | 32 | Implemented |
| Colorama | `ec.color.colorama` | 20 | GPU | 32 | Implemented |
| Convolution Kernel | `ec.color.cckernel` | 12 | GPU | 32 | Implemented |
| Curves | `ec.color.curves` | 0 | GPU | 32 | Implemented |
| Equalize | `ec.color.equalize` | 2 | GPU | 32 | Implemented |
| Exposure | `ec.color.exposure` | 14 | GPU | 32 | Implemented |
@@ -112,7 +112,7 @@ Effects are addressed by id (`ec.<category>.<name>`) or display name in commands
| Leave Color | `ec.color.leavecolor` | 5 | GPU | 32 | Implemented |
| Levels | `ec.color.levels` | 36 | GPU | 32 | Implemented |
| Levels (Individual Controls) | `ec.color.levelsic` | 27 | GPU | 32 | Implemented |
| Lumetri Color | `ec.color.lumetri` | 66 | GPU | 32 | Implemented |
| Multi-Tone Tint | `ec.color.cctoner` | 7 | GPU | 32 | Implemented |
| OCIO CDL Transform | `ec.color.ociocdl` | 12 | GPU | 32 | Implemented |
| OCIO Color Space Transform | `ec.color.ociocolorspace` | 7 | GPU | 32 | Implemented |
| OCIO Display Transform | `ec.color.ociodisplay` | 9 | GPU | 32 | Implemented |
@@ -133,40 +133,40 @@ Effects are addressed by id (`ec.<category>.<name>`) or display name in commands
|---|---|---:|:-:|:-:|---|
| Bezier Warp | `ec.distort.bezierwarp` | 13 | GPU | 32 | Implemented |
| Bulge | `ec.distort.bulge` | 6 | GPU | 32 | Implemented |
| CC Bend It | `ec.distort.ccbendit` | 4 | GPU | 32 | Implemented |
| CC Bender | `ec.distort.ccbender` | 5 | GPU | 32 | Implemented |
| CC Blobbylize | `ec.distort.ccblobbylize` | 15 | GPU | 32 | Implemented |
| CC Flo Motion | `ec.distort.ccflomotion` | 7 | GPU | 32 | Implemented |
| CC Griddler | `ec.distort.ccgriddler` | 5 | GPU | 32 | Implemented |
| CC Lens | `ec.distort.cclens` | 3 | GPU | 32 | Implemented |
| CC Page Turn | `ec.distort.ccpageturn` | 7 | GPU | 32 | Implemented |
| CC Power Pin | `ec.distort.ccpowerpin` | 10 | GPU | 32 | Implemented |
| CC Ripple Pulse | `ec.distort.ccripplepulse` | 5 | GPU | 32 | Implemented |
| CC Slant | `ec.distort.ccslant` | 4 | GPU | 32 | Implemented |
| CC Smear | `ec.distort.ccsmear` | 4 | GPU | 32 | Implemented |
| CC Split | `ec.distort.ccsplit` | 3 | GPU | 32 | Implemented |
| CC Split 2 | `ec.distort.ccsplit2` | 4 | GPU | 32 | Implemented |
| CC Tiler | `ec.distort.cctiler` | 3 | GPU | 32 | Implemented |
| Corner Pin | `ec.distort.cornerpin` | 4 | GPU | 32 | Implemented |
| Detail-preserving Upscale | `ec.distort.upscale` | 4 | | 32 | Implemented |
| Directional Smear | `ec.distort.ccsmear` | 4 | GPU | 32 | Implemented |
| Displacement Map | `ec.distort.displacementmap` | 8 | GPU | 32 | Implemented |
| Dual Lens Warp | `ec.distort.ccflomotion` | 7 | GPU | 32 | Implemented |
| Dual Split Warp | `ec.distort.ccsplit2` | 4 | GPU | 32 | Implemented |
| Flexible Bend | `ec.distort.ccbender` | 5 | GPU | 32 | Implemented |
| Lens Distortion | `ec.distort.cclens` | 3 | GPU | 32 | Implemented |
| Liquify | `ec.distort.liquify` | 13 | GPU | 32 | Implemented |
| Magnify | `ec.distort.magnify` | 10 | GPU | 32 | Implemented |
| Mesh Warp | `ec.distort.meshwarp` | 3 | GPU | 32 | Implemented |
| Mirror | `ec.distort.mirror` | 2 | GPU | 32 | Implemented |
| Offset | `ec.distort.offset` | 2 | GPU | 32 | Implemented |
| Optics Compensation | `ec.distort.opticscompensation` | 6 | GPU | 32 | Implemented |
| Organic Displacement | `ec.distort.ccblobbylize` | 15 | GPU | 32 | Implemented |
| Page Curl | `ec.distort.ccpageturn` | 7 | GPU | 32 | Implemented |
| Perspective Pin | `ec.distort.ccpowerpin` | 10 | GPU | 32 | Implemented |
| Polar Coordinates | `ec.distort.polar` | 2 | GPU | 32 | Implemented |
| Pulsed Ripple | `ec.distort.ccripplepulse` | 5 | GPU | 32 | Implemented |
| Puppet | `ec.distort.puppet` | 1 | | 32 | Implemented |
| Reshape | `ec.distort.reshape` | 6 | GPU | 32 | Implemented |
| Ripple | `ec.distort.ripple` | 7 | GPU | 32 | Implemented |
| Rolling Shutter Repair | `ec.distort.rollingshutterrepair` | 5 | | 32 | Implemented |
| Scaled Tiles | `ec.distort.cctiler` | 3 | GPU | 32 | Implemented |
| Slant | `ec.distort.ccslant` | 4 | GPU | 32 | Implemented |
| Smear | `ec.distort.smear` | 8 | GPU | 32 | Implemented |
| Spherize | `ec.distort.spherize` | 2 | GPU | 32 | Implemented |
| Split Warp | `ec.distort.ccsplit` | 3 | GPU | 32 | Implemented |
| Tile Grid | `ec.distort.ccgriddler` | 5 | GPU | 32 | Implemented |
| Transform | `ec.distort.transform` | 12 | GPU | 32 | Implemented |
| Turbulent Displace | `ec.distort.turbulentdisplace` | 11 | GPU | 32 | Implemented |
| Twirl | `ec.distort.twirl` | 3 | GPU | 32 | Implemented |
| Twirl (Legacy) | `ec.distort.twirllegacy` | 3 | GPU | 32 | Implemented |
| Two-Point Bend | `ec.distort.ccbendit` | 4 | GPU | 32 | Implemented |
| Warp | `ec.distort.warp` | 5 | GPU | 32 | Implemented |
| Warp Stabilizer | `ec.distort.warpstabilizer` | 20 | | 32 | Implemented |
| Wave Warp | `ec.distort.wavewarp` | 7 | GPU | 32 | Implemented |
@@ -194,11 +194,6 @@ Effects are addressed by id (`ec.<category>.<name>`) or display name in commands
| Audio Spectrum | `ec.generate.audiospectrum` | 23 | GPU | 32 | Implemented |
| Audio Waveform | `ec.generate.audiowaveform` | 17 | GPU | 32 | Implemented |
| Beam | `ec.generate.beam` | 11 | GPU | 32 | Implemented |
| CC Glue Gun | `ec.generate.ccgluegun` | 7 | GPU | 32 | Implemented |
| CC Light Burst 2.5 | `ec.generate.cclightburst` | 6 | GPU | 32 | Implemented |
| CC Light Rays | `ec.generate.cclightrays` | 8 | GPU | 32 | Implemented |
| CC Light Sweep | `ec.generate.cclightsweep` | 9 | GPU | 32 | Implemented |
| CC Threads | `ec.generate.ccthreads` | 8 | GPU | 32 | Implemented |
| Cell Pattern | `ec.generate.cellpattern` | 14 | GPU | 32 | Implemented |
| Checkerboard | `ec.generate.checkerboard` | 10 | GPU | 32 | Implemented |
| Circle | `ec.generate.circle` | 11 | GPU | 32 | Implemented |
@@ -209,11 +204,16 @@ Effects are addressed by id (`ec.<category>.<name>`) or display name in commands
| Gradient Ramp | `ec.generate.gradientramp` | 7 | GPU | 32 | Implemented |
| Grid | `ec.generate.grid` | 12 | GPU | 32 | Implemented |
| Lens Flare | `ec.generate.lensflare` | 4 | GPU | 32 | Implemented |
| Light Rays | `ec.generate.cclightrays` | 8 | GPU | 32 | Implemented |
| Light Sweep | `ec.generate.cclightsweep` | 9 | GPU | 32 | Implemented |
| Paint Beads | `ec.generate.ccgluegun` | 7 | GPU | 32 | Implemented |
| Paint Bucket | `ec.generate.paintbucket` | 11 | GPU | 32 | Implemented |
| Radial Light Burst | `ec.generate.cclightburst` | 6 | GPU | 32 | Implemented |
| Radio Waves | `ec.generate.radiowaves` | 31 | GPU | 32 | Implemented |
| Scribble | `ec.generate.scribble` | 25 | GPU | 32 | Implemented |
| Stroke | `ec.generate.stroke` | 11 | GPU | 32 | Implemented |
| Vegas | `ec.generate.vegas` | 26 | GPU | 32 | Implemented |
| Woven Threads | `ec.generate.ccthreads` | 8 | GPU | 32 | Implemented |
| Write-on | `ec.generate.writeon` | 10 | GPU | 32 | Implemented |
## Immersive Video
@@ -238,15 +238,15 @@ Effects are addressed by id (`ec.<category>.<name>`) or display name in commands
| Effect | Id | Params | GPU | 32 | Status |
|---|---|---:|:-:|:-:|---|
| Advanced Spill Suppressor | `ec.key.advancedspill` | 8 | GPU | 32 | Implemented |
| CC Simple Wire Removal | `ec.key.ccsimplewireremoval` | 7 | GPU | 32 | Implemented |
| Color Difference Key | `ec.key.colordifference` | 16 | GPU | 32 | Implemented |
| Color Range | `ec.key.colorrange` | 8 | GPU | 32 | Implemented |
| Difference Matte | `ec.key.differencematte` | 6 | GPU | 32 | Implemented |
| Extract | `ec.key.extract` | 6 | GPU | 32 | Implemented |
| Inner/Outer Key | `ec.key.innerouter` | 88 | GPU | 32 | Implemented |
| Key Cleaner | `ec.key.keycleaner` | 4 | GPU | 32 | Implemented |
| Key Light | `ec.keying.keylight` | 56 | GPU | 32 | Implemented |
| Line Removal | `ec.key.ccsimplewireremoval` | 7 | GPU | 32 | Implemented |
| Linear Color Key | `ec.key.linearcolor` | 6 | GPU | 32 | Implemented |
| Screen Color Key | `ec.keying.keylight` | 56 | GPU | 32 | Implemented |
| Screen Key | `ec.key.screen` | 11 | GPU | 32 | Implemented |
| Unmult | `ec.key.unmult` | 6 | GPU | 32 | Implemented |
@@ -255,12 +255,12 @@ Effects are addressed by id (`ec.<category>.<name>`) or display name in commands
| Effect | Id | Params | GPU | 32 | Status |
|---|---|---:|:-:|:-:|---|
| Matte Choker | `ec.matte.mattechoker` | 7 | GPU | 32 | Implemented |
| Mocha shape | `ec.obsolete.mochashape` | 6 | | 32 | Implemented |
| Object Matte | `ec.matte.objectmatte` | 13 | | 32 | Implemented |
| Refine Hard Matte | `ec.matte.refinehard` | 16 | GPU | 32 | Implemented |
| Refine Soft Matte | `ec.matte.refinesoft` | 18 | GPU | 32 | Implemented |
| Roto Brush & Refine Edge | `ec.matte.rotobrush` | 25 | | 32 | Implemented |
| Simple Choker | `ec.matte.simplechoker` | 2 | GPU | 32 | Implemented |
| Tracked Shape Matte | `ec.obsolete.mochashape` | 6 | | 32 | Implemented |
## Noise & Grain
@@ -308,65 +308,65 @@ Effects are addressed by id (`ec.<category>.<name>`) or display name in commands
| 3D Glasses | `ec.perspective.3dglasses` | 8 | GPU | 32 | Implemented |
| Bevel Alpha | `ec.perspective.bevelalpha` | 4 | GPU | 32 | Implemented |
| Bevel Edges | `ec.perspective.beveledges` | 4 | GPU | 32 | Implemented |
| CC Cylinder | `ec.perspective.cccylinder` | 15 | GPU | 32 | Implemented |
| CC Environment | `ec.perspective.ccenvironment` | 4 | GPU | 32 | Implemented |
| CC Sphere | `ec.perspective.ccsphere` | 14 | GPU | 32 | Implemented |
| CC Spotlight | `ec.perspective.ccspotlight` | 8 | GPU | 32 | Implemented |
| Cylinder Wrap | `ec.perspective.cccylinder` | 15 | GPU | 32 | Implemented |
| Drop Shadow | `ec.perspective.dropshadow` | 6 | GPU | 32 | Implemented |
| Environment Map | `ec.perspective.ccenvironment` | 4 | GPU | 32 | Implemented |
| Radial Shadow | `ec.perspective.radialshadow` | 9 | GPU | 32 | Implemented |
| Sphere Wrap | `ec.perspective.ccsphere` | 14 | GPU | 32 | Implemented |
| Surface Spotlight | `ec.perspective.ccspotlight` | 8 | GPU | 32 | Implemented |
## Simulation
| Effect | Id | Params | GPU | 32 | Status |
|---|---|---:|:-:|:-:|---|
| CC Ball Action | `ec.sim.ccballaction` | 8 | GPU | 32 | Implemented |
| CC Bubbles | `ec.sim.ccbubbles` | 7 | GPU | 32 | Implemented |
| CC Drizzle | `ec.sim.ccdrizzle` | 14 | GPU | 32 | Implemented |
| CC Hair | `ec.sim.cchair` | 20 | GPU | 32 | Implemented |
| CC Mr. Mercury | `ec.sim.ccmrmercury` | 23 | GPU | 32 | Implemented |
| CC Particle Systems II | `ec.sim.ccparticlesystems2` | 21 | GPU | 32 | Implemented |
| CC Particle World | `ec.sim.ccparticleworld` | 36 | GPU | 32 | Implemented |
| CC Pixel Polly | `ec.sim.ccpixelpolly` | 10 | GPU | 32 | Implemented |
| CC Rainfall | `ec.sim.ccrainfall` | 14 | GPU | 32 | Implemented |
| CC Scatterize | `ec.sim.ccscatterize` | 4 | GPU | 32 | Implemented |
| CC Snowfall | `ec.sim.ccsnowfall` | 19 | GPU | 32 | Implemented |
| CC Star Burst | `ec.sim.ccstarburst` | 6 | GPU | 32 | Implemented |
| Ball Grid | `ec.sim.ccballaction` | 8 | GPU | 32 | Implemented |
| Bubbles | `ec.sim.ccbubbles` | 7 | GPU | 32 | Implemented |
| Card Dance | `ec.sim.carddance` | 53 | GPU | 32 | Implemented |
| Caustics | `ec.sim.caustics` | 28 | GPU | 32 | Implemented |
| Foam | `ec.sim.foam` | 36 | GPU | 32 | Implemented |
| Liquid Particles | `ec.sim.ccmrmercury` | 23 | GPU | 32 | Implemented |
| Particle Emitter 2D | `ec.sim.ccparticlesystems2` | 21 | GPU | 32 | Implemented |
| Particle Emitter 3D | `ec.sim.ccparticleworld` | 36 | GPU | 32 | Implemented |
| Particle Playground | `ec.sim.particleplayground` | 92 | GPU | 32 | Implemented |
| Pixel Scatter | `ec.sim.ccscatterize` | 4 | GPU | 32 | Implemented |
| Pixel Shatter | `ec.sim.ccpixelpolly` | 10 | GPU | 32 | Implemented |
| Rainfall | `ec.sim.ccrainfall` | 14 | GPU | 32 | Implemented |
| Shatter | `ec.sim.shatter` | 60 | GPU | 32 | Implemented |
| Snowfall | `ec.sim.ccsnowfall` | 19 | GPU | 32 | Implemented |
| Starfield | `ec.sim.ccstarburst` | 6 | GPU | 32 | Implemented |
| Surface Fibers | `ec.sim.cchair` | 20 | GPU | 32 | Implemented |
| Water Ripples | `ec.sim.ccdrizzle` | 14 | GPU | 32 | Implemented |
| Wave World | `ec.sim.waveworld` | 35 | GPU | 32 | Implemented |
## Stylize
| Effect | Id | Params | GPU | 32 | Status |
|---|---|---:|:-:|:-:|---|
| Block Reveal | `ec.stylize.ccblockload` | 5 | GPU | 32 | Implemented |
| Brush Strokes | `ec.stylize.brushstrokes` | 7 | GPU | 32 | Implemented |
| CC Block Load | `ec.stylize.ccblockload` | 5 | GPU | 32 | Implemented |
| CC Burn Film | `ec.stylize.ccburnfilm` | 3 | GPU | 32 | Implemented |
| CC Glass | `ec.stylize.ccglass` | 17 | GPU | 32 | Implemented |
| CC HexTile | `ec.stylize.cchextile` | 5 | GPU | 32 | Implemented |
| CC Kaleida | `ec.stylize.cckaleida` | 4 | GPU | 32 | Implemented |
| CC Mr. Smoothie | `ec.stylize.ccmrsmoothie` | 7 | GPU | 32 | Implemented |
| CC Plastic | `ec.stylize.ccplastic` | 18 | GPU | 32 | Implemented |
| CC RepeTile | `ec.stylize.ccrepetile` | 5 | GPU | 32 | Implemented |
| CC Threshold | `ec.stylize.ccthreshold` | 4 | GPU | 32 | Implemented |
| CC Threshold RGB | `ec.stylize.ccthresholdrgb` | 7 | GPU | 32 | Implemented |
| CC Vignette | `ec.stylize.ccvignette` | 4 | GPU | 32 | Implemented |
| Cartoon | `ec.stylize.cartoon` | 12 | GPU | 32 | Implemented |
| Channel Threshold | `ec.stylize.ccthreshold` | 4 | GPU | 32 | Implemented |
| Color Emboss | `ec.stylize.coloremboss` | 4 | GPU | 32 | Implemented |
| Edge Tile Repeat | `ec.stylize.ccrepetile` | 5 | GPU | 32 | Implemented |
| Emboss | `ec.stylize.emboss` | 4 | GPU | 32 | Implemented |
| Film Burn | `ec.stylize.ccburnfilm` | 3 | GPU | 32 | Implemented |
| Find Edges | `ec.stylize.findedges` | 2 | GPU | 32 | Implemented |
| Glass Relief | `ec.stylize.ccglass` | 17 | GPU | 32 | Implemented |
| Glow | `ec.stylize.glow` | 14 | GPU | 32 | Implemented |
| Hexagonal Tiles | `ec.stylize.cchextile` | 5 | GPU | 32 | Implemented |
| Kaleidoscope | `ec.stylize.cckaleida` | 4 | GPU | 32 | Implemented |
| Mosaic | `ec.stylize.mosaic` | 3 | GPU | 32 | Implemented |
| Motion Tile | `ec.stylize.motiontile` | 8 | GPU | 32 | Implemented |
| Palette Map | `ec.stylize.ccmrsmoothie` | 7 | GPU | 32 | Implemented |
| Plastic Shading | `ec.stylize.ccplastic` | 18 | GPU | 32 | Implemented |
| Posterize | `ec.stylize.posterize` | 1 | GPU | 32 | Implemented |
| RGB Threshold | `ec.stylize.ccthresholdrgb` | 7 | GPU | 32 | Implemented |
| Roughen Edges | `ec.stylize.roughenedges` | 13 | GPU | 32 | Implemented |
| Scatter | `ec.stylize.scatter` | 3 | GPU | 32 | Implemented |
| Strobe Light | `ec.stylize.strobe` | 7 | GPU | 32 | Implemented |
| Texturize | `ec.stylize.texturize` | 4 | GPU | 32 | Implemented |
| Threshold | `ec.stylize.threshold` | 1 | GPU | 32 | Implemented |
| Vignette | `ec.stylize.ccvignette` | 4 | GPU | 32 | Implemented |
## Text
@@ -379,11 +379,11 @@ Effects are addressed by id (`ec.<category>.<name>`) or display name in commands
| Effect | Id | Params | GPU | 32 | Status |
|---|---|---:|:-:|:-:|---|
| CC Force Motion Blur | `ec.time.ccforcemotionblur` | 4 | GPU | 32 | Implemented |
| CC Wide Time | `ec.time.ccwidetime` | 3 | GPU | 32 | Implemented |
| Echo | `ec.time.echo` | 5 | GPU | 32 | Implemented |
| Pixel Motion Blur | `ec.time.pixelmotionblur` | 4 | GPU | 32 | Implemented |
| Posterize Time | `ec.time.posterizetime` | 1 | GPU | 32 | Implemented |
| Temporal Blend | `ec.time.ccwidetime` | 3 | GPU | 32 | Implemented |
| Temporal Motion Blur | `ec.time.ccforcemotionblur` | 4 | GPU | 32 | Implemented |
| Time Difference | `ec.time.timedifference` | 5 | GPU | 32 | Implemented |
| Time Displacement | `ec.time.timedisplacement` | 4 | GPU | 32 | Implemented |
| Timewarp | `ec.time.timewarp` | 28 | GPU | 32 | Implemented |
@@ -393,29 +393,28 @@ Effects are addressed by id (`ec.<category>.<name>`) or display name in commands
| Effect | Id | Params | GPU | 32 | Status |
|---|---|---:|:-:|:-:|---|
| Block Dissolve | `ec.transition.blockdissolve` | 5 | GPU | 32 | Implemented |
| CC Glass Wipe | `ec.transition.ccglasswipe` | 5 | GPU | 32 | Implemented |
| CC Grid Wipe | `ec.transition.ccgridwipe` | 7 | GPU | 32 | Implemented |
| CC Image Wipe | `ec.transition.ccimagewipe` | 7 | GPU | 32 | Implemented |
| CC Jaws | `ec.transition.ccjaws` | 6 | GPU | 32 | Implemented |
| CC Light Wipe | `ec.transition.cclightwipe` | 8 | GPU | 32 | Implemented |
| CC Line Sweep | `ec.transition.cclinesweep` | 5 | GPU | 32 | Implemented |
| CC Radial ScaleWipe | `ec.transition.ccradialscalewipe` | 3 | GPU | 32 | Implemented |
| CC Scale Wipe | `ec.transition.ccscalewipe` | 3 | GPU | 32 | Implemented |
| CC Twister | `ec.transition.cctwister` | 5 | GPU | 32 | Implemented |
| CC WarpoMatic | `ec.transition.ccwarpomatic` | 8 | GPU | 32 | Implemented |
| Card Wipe | `ec.transition.cardwipe` | 44 | GPU | 32 | Implemented |
| Glass Wipe | `ec.transition.ccglasswipe` | 5 | GPU | 32 | Implemented |
| Gradient Wipe | `ec.transition.gradientwipe` | 5 | GPU | 32 | Implemented |
| Grid Wipe | `ec.transition.ccgridwipe` | 7 | GPU | 32 | Implemented |
| Iris Wipe | `ec.transition.iriswipe` | 7 | GPU | 32 | Implemented |
| Light Wipe | `ec.transition.cclightwipe` | 8 | GPU | 32 | Implemented |
| Line Sweep | `ec.transition.cclinesweep` | 5 | GPU | 32 | Implemented |
| Linear Wipe | `ec.transition.linearwipe` | 3 | GPU | 32 | Implemented |
| Luminance Image Wipe | `ec.transition.ccimagewipe` | 7 | GPU | 32 | Implemented |
| Radial Scale Wipe | `ec.transition.ccradialscalewipe` | 3 | GPU | 32 | Implemented |
| Radial Wipe | `ec.transition.radialwipe` | 5 | GPU | 32 | Implemented |
| Scale Wipe | `ec.transition.ccscalewipe` | 3 | GPU | 32 | Implemented |
| Serrated Wipe | `ec.transition.ccjaws` | 6 | GPU | 32 | Implemented |
| Twist Wipe | `ec.transition.cctwister` | 5 | GPU | 32 | Implemented |
| Venetian Blinds | `ec.transition.venetian` | 4 | GPU | 32 | Implemented |
| Warp Dissolve | `ec.transition.ccwarpomatic` | 8 | GPU | 32 | Implemented |
## Utility
| Effect | Id | Params | GPU | 32 | Status |
|---|---|---:|:-:|:-:|---|
| Apply Color LUT | `ec.utility.applylut` | 1 | GPU | 32 | Implemented |
| CC Overbrights | `ec.utility.ccoverbrights` | 2 | GPU | 32 | Implemented |
| Cineon Converter | `ec.utility.cineon` | 7 | GPU | 32 | Implemented |
| Color Profile Converter | `ec.utility.colorprofileconverter` | 7 | GPU | 32 | Implemented |
| Face Measurements | `ec.utility.facemeasurements` | 14 | | 32 | Implemented |
@@ -423,4 +422,5 @@ Effects are addressed by id (`ec.<category>.<name>`) or display name in commands
| Grow Bounds | `ec.utility.growbounds` | 1 | GPU | 32 | Implemented |
| HDR Compander | `ec.utility.hdrcompander` | 3 | GPU | 32 | Implemented |
| HDR Highlight Compression | `ec.utility.hdrcompression` | 1 | GPU | 32 | Implemented |
| Out-of-Range Display | `ec.utility.ccoverbrights` | 2 | GPU | 32 | Implemented |
+108
View File
@@ -0,0 +1,108 @@
# Descriptive feature names
Related to #1365. This is a naming cleanup, not a trademark clearance or a product rename.
## Naming policy
Use short, descriptive labels for EffectCraft implementations. Do not reuse a vendor prefix or
coined feature name as our branding. Qualify similar effects by what distinguishes them; each
English display name remains unique across the registry.
- Renderer: **GPU Acceleration** / **Software Rendering**.
- Panel: **Video Scopes**.
- The table below covers the 69 former CC effects plus color grading, the shape matte and keying.
## Compatibility contract
Only presentation names change. Effect IDs, command IDs, parameter IDs, enum values, panel IDs,
serialized types and AEP import/export match names stay unchanged. Old effect display names
remain case-insensitive lookup and search aliases. Existing project instance names, custom names,
expressions, animation and values are not rewritten. The UI displays a current label for an exact
legacy default name, optionally followed by its numeric instance suffix; all other names stay
verbatim. A user-entered name identical to a legacy default cannot be distinguished from it, but
its saved value is still retained.
External format specifications, comparison documents, attribution records and compatibility
fixtures may still name the external product or effect they actually describe.
## Display mapping
| Stable ID | Previous display name | Current display name |
|---|---|---|
| `ec.sim.ccballaction` | CC Ball Action | Ball Grid |
| `ec.distort.ccbendit` | CC Bend It | Two-Point Bend |
| `ec.distort.ccbender` | CC Bender | Flexible Bend |
| `ec.distort.ccblobbylize` | CC Blobbylize | Organic Displacement |
| `ec.stylize.ccblockload` | CC Block Load | Block Reveal |
| `ec.sim.ccbubbles` | CC Bubbles | Bubbles |
| `ec.stylize.ccburnfilm` | CC Burn Film | Film Burn |
| `ec.color.cccolorneutralizer` | CC Color Neutralizer | Color Neutralizer |
| `ec.color.cccoloroffset` | CC Color Offset | Channel Offset |
| `ec.channel.cccomposite` | CC Composite | Source Composite |
| `ec.blur.cccross` | CC Cross Blur | Cross Blur |
| `ec.perspective.cccylinder` | CC Cylinder | Cylinder Wrap |
| `ec.sim.ccdrizzle` | CC Drizzle | Water Ripples |
| `ec.perspective.ccenvironment` | CC Environment | Environment Map |
| `ec.distort.ccflomotion` | CC Flo Motion | Dual Lens Warp |
| `ec.time.ccforcemotionblur` | CC Force Motion Blur | Temporal Motion Blur |
| `ec.stylize.ccglass` | CC Glass | Glass Relief |
| `ec.transition.ccglasswipe` | CC Glass Wipe | Glass Wipe |
| `ec.generate.ccgluegun` | CC Glue Gun | Paint Beads |
| `ec.transition.ccgridwipe` | CC Grid Wipe | Grid Wipe |
| `ec.distort.ccgriddler` | CC Griddler | Tile Grid |
| `ec.sim.cchair` | CC Hair | Surface Fibers |
| `ec.stylize.cchextile` | CC HexTile | Hexagonal Tiles |
| `ec.transition.ccimagewipe` | CC Image Wipe | Luminance Image Wipe |
| `ec.transition.ccjaws` | CC Jaws | Serrated Wipe |
| `ec.stylize.cckaleida` | CC Kaleida | Kaleidoscope |
| `ec.color.cckernel` | CC Kernel | Convolution Kernel |
| `ec.distort.cclens` | CC Lens | Lens Distortion |
| `ec.generate.cclightburst` | CC Light Burst 2.5 | Radial Light Burst |
| `ec.generate.cclightrays` | CC Light Rays | Light Rays |
| `ec.generate.cclightsweep` | CC Light Sweep | Light Sweep |
| `ec.transition.cclightwipe` | CC Light Wipe | Light Wipe |
| `ec.transition.cclinesweep` | CC Line Sweep | Line Sweep |
| `ec.sim.ccmrmercury` | CC Mr. Mercury | Liquid Particles |
| `ec.stylize.ccmrsmoothie` | CC Mr. Smoothie | Palette Map |
| `ec.utility.ccoverbrights` | CC Overbrights | Out-of-Range Display |
| `ec.distort.ccpageturn` | CC Page Turn | Page Curl |
| `ec.sim.ccparticlesystems2` | CC Particle Systems II | Particle Emitter 2D |
| `ec.sim.ccparticleworld` | CC Particle World | Particle Emitter 3D |
| `ec.sim.ccpixelpolly` | CC Pixel Polly | Pixel Shatter |
| `ec.stylize.ccplastic` | CC Plastic | Plastic Shading |
| `ec.distort.ccpowerpin` | CC Power Pin | Perspective Pin |
| `ec.blur.ccradial` | CC Radial Blur | Variable Radial Blur |
| `ec.blur.ccradialfast` | CC Radial Fast Blur | Fast Radial Blur |
| `ec.transition.ccradialscalewipe` | CC Radial ScaleWipe | Radial Scale Wipe |
| `ec.sim.ccrainfall` | CC Rainfall | Rainfall |
| `ec.stylize.ccrepetile` | CC RepeTile | Edge Tile Repeat |
| `ec.distort.ccripplepulse` | CC Ripple Pulse | Pulsed Ripple |
| `ec.transition.ccscalewipe` | CC Scale Wipe | Scale Wipe |
| `ec.sim.ccscatterize` | CC Scatterize | Pixel Scatter |
| `ec.key.ccsimplewireremoval` | CC Simple Wire Removal | Line Removal |
| `ec.distort.ccslant` | CC Slant | Slant |
| `ec.distort.ccsmear` | CC Smear | Directional Smear |
| `ec.sim.ccsnowfall` | CC Snowfall | Snowfall |
| `ec.perspective.ccsphere` | CC Sphere | Sphere Wrap |
| `ec.distort.ccsplit` | CC Split | Split Warp |
| `ec.distort.ccsplit2` | CC Split 2 | Dual Split Warp |
| `ec.perspective.ccspotlight` | CC Spotlight | Surface Spotlight |
| `ec.sim.ccstarburst` | CC Star Burst | Starfield |
| `ec.generate.ccthreads` | CC Threads | Woven Threads |
| `ec.stylize.ccthreshold` | CC Threshold | Channel Threshold |
| `ec.stylize.ccthresholdrgb` | CC Threshold RGB | RGB Threshold |
| `ec.distort.cctiler` | CC Tiler | Scaled Tiles |
| `ec.color.cctoner` | CC Toner | Multi-Tone Tint |
| `ec.transition.cctwister` | CC Twister | Twist Wipe |
| `ec.blur.ccvector` | CC Vector Blur | Vector Blur |
| `ec.stylize.ccvignette` | CC Vignette | Vignette |
| `ec.transition.ccwarpomatic` | CC WarpoMatic | Warp Dissolve |
| `ec.time.ccwidetime` | CC Wide Time | Temporal Blend |
| `ec.color.lumetri` | Lumetri Color | Color Grading |
| `ec.obsolete.mochashape` | Mocha shape | Tracked Shape Matte |
| `ec.keying.keylight` | Key Light | Screen Color Key |
`Roto Brush & Refine Edge` and `Warp Stabilizer` keep their current names; renaming them is
deferred.
No effect algorithms or formats are changed.
+6
View File
@@ -266,6 +266,12 @@ Issues #41–#47 (all from the Linux AppImage 0.1.1, 5 October): panning the vie
The second means reading another implementation of the format, which AGENTS.md rules out
unless the clean-room scope allows it.
- Also in this area: relative footage paths and relinking when a project moves (gap 18).
- Placed PDF / Illustrator footage of an `.aep` is framed as After Effects places it (the ArtBox
clipped to the crop box, `/Rotate` ignored) and drawn to fill the size After Effects stored
(#3099), measured with hand-written PDFs named `.ai`. Not yet measured: files saved by
Illustrator itself (artboards, bleed, art past the artboard, private data), a CropBox without
an ArtBox, `.pdf` names, and EPS files (they keep their bounding box at their own size, not
the placed framing).
- Done when: the decision is recorded and, if approved, a corpus of real-world-shaped projects
opens with its comps, layers, keyframes, effects and expressions intact.
+34 -15
View File
@@ -11,7 +11,7 @@ Guide):
| After Effects | EffectCraft | |
|---|---|---|
| Effect plug-ins (C/C++ SDK, `.aex` / `.plugin`) | [Effect plug-ins](#effect-plug-ins): WebAssembly modules (plug-in API v1) or Rust; the `Plug-ins` folder next to the settings loads at start-up | Different ABI: After Effects SDK plug-ins can't run (G8) |
| Effect plug-ins (C/C++ SDK, `.aex` / `.plugin`) | [Effect plug-ins](#effect-plug-ins): WebAssembly modules (WebAssembly ABI 1 and 2) or Rust; the `Plug-ins` folder next to the settings loads at start-up | Different ABI: After Effects SDK plug-ins can't run (G8) |
| Scripts folder: its scripts are listed in File ▸ Scripts | `Scripts/` in the settings folder (File ▸ Scripts ▸ Install Script File… copies a script there), listed in File ▸ Scripts with the bundled samples; a subfolder (one level) is a submenu named after it | Same |
| File ▸ Scripts ▸ Run Script File… (`.jsx`, `.jsxbin`) | `.jsx` / `.js` | Gap: `.jsxbin` (an undocumented binary encoding) |
| File ▸ Scripts ▸ Recent Script Files: the 10 most recently run scripts; Cmd+Option+Shift+D (Ctrl+Alt+Shift+D on Windows) reruns one | File ▸ Scripts ▸ Recent Script Files lists the 10 scripts run last (script files and File ▸ Scripts entries, newest first, kept in the settings); Cmd+Alt+Shift+D runs the most recent one again (`file.runScript {"recent": 0}`, a key that can be changed in Edit ▸ Keyboard Shortcuts) | Same |
@@ -152,7 +152,7 @@ example of a keyframe tool.
## Effect plug-ins
EffectCraft loads third-party effects through a small, versioned plug-in API (**API version 2**; WebAssembly ABI 1).
EffectCraft loads third-party effects through a small, versioned plug-in API (**API version 2**; WebAssembly ABI 1 and 2).
A plug-in effect behaves exactly like a built-in one: it is listed in Effects & Presets (and the
Effect menu) under its category, applied by id (`effect.apply {"effect": "org.example.posterize"}`)
or display name, its parameters are ordinary properties (keyframes, expressions, Effect Controls,
@@ -178,7 +178,8 @@ author, source, params}]}`.
* **Parameters** arrive flattened to `f64`s in the order they are declared: slider, angle,
checkbox (0 / 1) and popup (0-based index) take one value, point two (already in **buffer
pixels**), colour four (RGBA 0–1).
* **Time** is layer time in seconds.
* **Time** is layer time in seconds. A WebAssembly module written for ABI 2 also gets the
layer's neighbouring frames at other times (see [WebAssembly ABI](#webassembly-abi)).
* Rendering must be **deterministic** and may run on several threads at once (a WebAssembly
plug-in gets one instance per thread).
* A failed render (an error code, a trap, running out of fuel) leaves the frame unchanged.
@@ -216,22 +217,36 @@ Every plug-in describes itself with a JSON manifest:
parameters; a slider needs `min ≤ default ≤ max` (and `sliderMin ≤ sliderMax`); the manifest
is at most 1 MiB.
### WebAssembly ABI (v1)
### WebAssembly ABI
A module with **no imports** that exports:
A module with **no imports** exports:
| export | signature | |
|---|---|---|
| `memory` | memory | linear memory shared with the host |
| `ec_api_version` | `() -> i32` | must return `1` |
| `ec_api_version` | `() -> i32` | `1` for ABI 1, `2` for ABI 2 (neighbouring frames) |
| `ec_manifest_ptr`, `ec_manifest_len` | `() -> i32` | the UTF-8 JSON manifest in memory |
| `ec_alloc` | `(bytes: i32) -> i32` | a buffer of at least `bytes` bytes, 8-byte aligned; it may reuse the previous one |
| `ec_render` | `(pixels: i32, width: i32, height: i32, params: i32, nparams: i32, time: f64, scale: f64) -> i32` | process the pixels in place; return 0 on success |
| `ec_render` (ABI 1) | `(pixels: i32, width: i32, height: i32, params: i32, nparams: i32, time: f64, scale: f64) -> i32` | process the pixels in place; return 0 on success |
| `ec_render2` (ABI 2) | `ec_render`'s arguments, then `prev: i32, prev_time: f64, next: i32, next_time: f64, flags: i32` | the same, with the neighbouring frames; return 0 on success |
For each frame the host calls `ec_alloc` once for a buffer holding the parameters (`nparams`
little-endian `f64`s) followed by the pixels (`width × height × 4` little-endian `f32`s), fills it,
calls `ec_render`, and reads the pixels back. Each call gets a fuel budget proportional to the
frame size; a module that loops forever stops with an error instead of hanging the app.
little-endian `f64`s) followed by the pixels (`width × height × 4` little-endian `f32`s,
premultiplied RGBA, row-major), fills it, calls the module's render export, and reads the pixels
back. An ABI 2 module gets two more pixel buffers after the current frame: the previous and next
frames, resampled onto the current buffer's grid. At a frame boundary they are the frames before
and after it (`time ± 1/fps`); between frames they are the two frames that bracket `time`.
The neighbour buffers are always allocated (zeroed when the layer has no pixels there, so a
module can read both without a null check). `flags` bit 0 is set when `prev` holds a real frame,
bit 1 when `next` does; `prev_time` / `next_time` are those frames' layer times in seconds (0
when absent). The ABI version is the module's `ec_api_version` and is independent of the
manifest's `api` (the native plug-in API): a module can use ABI 2 while its manifest says
`"api": 1`. Because an ABI 2 module reads other times, its layer is keyed on the layer time in
the render cache; ABI 1 modules keep the time-independent key.
Each call gets a fuel budget proportional to the frame size; a module that loops forever stops
with an error instead of hanging the app.
#### Example
@@ -324,8 +339,10 @@ register_plugin(Arc::new(Swap(manifest)))?; // before the UI builds its menus
## Plug-in API 2 (native plug-ins)
API 2 is for Rust plug-ins and for hosts that bring effects from elsewhere (such as
[external effect helpers](external-helpers.md)); the WebAssembly ABI stays at 1. Manifests with `"api": 1` or `2` are accepted,
`effect.plugins.list` reports `api: 2`, and up to 1024 plug-in effects can be registered.
[external effect helpers](external-helpers.md)); the WebAssembly ABI is versioned separately
(ABI 2 adds the neighbouring frames, see [WebAssembly ABI](#webassembly-abi)). Manifests with
`"api": 1` or `2` are accepted, `effect.plugins.list` reports `api: 2`, and up to 1024 plug-in
effects can be registered.
* **New parameter types**: `point3` (`default` `[x, y, z]`; x, y arrive in buffer pixels, z as is),
`layer` (another layer of the composition; flattens to its id, -1 for none, read with
@@ -354,9 +371,11 @@ API 2 is for Rust plug-ins and for hosts that bring effects from elsewhere (such
### Compatibility
The API version is checked when a plug-in loads: a manifest or module for another version is
refused with a message. Within a version the contract above does not change; additions (new
parameter types, new optional exports) bump the version.
The API version is checked when a plug-in loads: this build implements plug-in API 1 and 2 and
WebAssembly ABI 1 and 2; a manifest or module for another version is refused with a message.
ABI 1 modules load and render unchanged; ABI 2 modules add `ec_render2` and the neighbouring
frames. Within a version the contract above does not change; additions (new parameter types,
new optional exports) bump the version.
## Plug-in Library
+1 -1
View File
@@ -174,7 +174,7 @@ the same futures with `passes::block_on`; they never wait there).
- **Render Queue**: `effectcraft_export::export_async` renders each frame in passes (frames
with deferred readbacks render one by one instead of in parallel batches) and encodes as
before (`Exporter::export_async`). As on the desktop, a job renders every frame on the
project's renderer (the worker's GPU with Mercury GPU Acceleration), not on whichever
project's renderer (the worker's GPU with GPU Acceleration), not on whichever
compositor measured faster, so runs don't differ by timing.
- **Analyses** (Warp Stabilizer, 3D Camera Tracker, Track Motion, mask and face tracking, Roto
Brush freeze and propagation): their work functions are `async`; started with `wait` inside