Display Color Space setting joins the live list; View3D::Default maps to view.3d.default for
the Assign Shortcut submenu; stub tests use the stubs that remain.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reconciled with main's keyframe labels (same Keyframe::label field; keys.setLabel and
keys.selectLabelGroup from main are kept, M14.5's duplicates removed; Edit ▸ Label on
selected keys delegates to the label helper), proxies (RenderOpts::proxy next to
nested_switches/draft_shadows), offloaded renders (Work carries nested_switches), wasm
audio pump (preview mix rate), variable font axes and mask feather points.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Layer > Camera > Create Stereo 3D Rig (left/right eye comps with expression-linked eye
cameras, Stereo 3D Controls effect, stereo comp through 3D Glasses), Create Orbit Null,
Create Cameras from 3D Model; Layer > Light > Create Lights from 3D Model
(KHR_lights_punctual), Control Light with Camera, Create Environment Light Background
Layer (equirectangular sky drawn through the camera). glTF cameras and punctual lights
are parsed by effectcraft-model.
Advanced 3D: per-sample motion blur over the comp shutter, and blend modes / track
mattes / Preserve Transparency composited through the 2D path in depth order.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The 3D Camera Tracker analysis joins the offloaded jobs. The disk cache stays off in the
browser (std::env::temp_dir panics on wasm32 once a config store exists).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Persistence: settings, shortcuts, recent projects, imported media, saved projects and
auto-saves live in OPFS (IndexedDB fallback) through an in-memory mirror flushed in the
background (apps/effectcraft-web/src/store.rs, persist.rs); ConfigStore gains FileOps so
auto-save / recovery work in the browser store; the session snapshot restores the last
project + editor state on reload; File > Open Recent works from storage.
- Audio: Web Audio output (AudioWorklet, ScriptProcessor fallback) fed by AudioPlayback::pump
on wasm32; A/V sync from AudioContext.currentTime; meters; unlock on first gesture.
- Background jobs: engine::offload (WorkerRequest/WorkerReply protocol, Offload trait,
run_request); Render Queue, tracker, mask tracker, Warp Stabilizer and Roto Freeze run in Web
Workers (a second engine instance on the shared compiled module), progress streamed back;
cancel terminates the worker.
- GPU: WebGPU viewer frames drawn straight from the compositor's texture (gpu_display on
wasm32 when the viewer draws plainly); async readback (Gpu::read_display_async) for pixels.
- PWA: manifest, service worker precaching the build (xtask fills list/version), icons copied
from assets/app-icon; COOP/COEP kept from cached responses; offline reload works.
- window.effectcraft: saveToBrowser, listStored, removeStored, flush; info() reports storage,
audio, gpu, workers.
- Tests: native store + protocol + offload (render, track, cancel) tests; smoke.mjs extended
(GPU path, worker render responsiveness, audio gesture + playback, reload persistence,
Open Recent, offline reload).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Shapes (SHP-2): Stroke Taper (pixels/percent start/end length, width, ease) and
Wave (amount, pixels/cycles, wavelength, phase) rendered as a variable-width
outline; Dash 2/Gap 2/Dash 3/Gap 3 (shape.dashes.add/remove, timeline +/-
buttons); radial gradient Highlight Length/Angle as a focal gradient.
Masks (MSK-1): mask feather points on the Mask Path (mask.featherPoint.*,
Mask Feather tool add/drag), per-point signed radius and tension, rendered
from the signed distance to the path; carried through vertex edits.
Motion blur (LYR-10): Adaptive Sample Limit comp setting; 2D layers take one
sample per pixel of shutter travel between Samples Per Frame and the limit.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Items (footage and comps) carry a proxy rendered in their place at the source's size when
its switch and Render Settings > Proxy Use allow it; Create Proxy queues a half-resolution
render whose post-render action attaches it. Interpret Footage gains Separate Fields
(upper/lower first, fields become frames at twice the rate), Guess alpha with matte colour,
explicit matte colour, Invert Alpha, Interpret As Linear Light; non-square footage, solids
and precomps are stretched by their pixel aspect in the comp. The four proxy stubs are gone.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comps expose controls (properties typed as text/color/slider/checkbox/point/angle/dropdown,
Media Replacement, groups, comments); precomp layers get an Essential Properties group whose
edits override per instance (Push to Comp / Revert); templates export/import as an open ZIP
(manifest.json + project subset + media + poster). Stretched precomps keep protected regions
at their original speed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
New crate effectcraft-model (L2): glTF 2.0 (.gltf/.glb, data URIs, external buffers and
images, PBR metallic-roughness with base/MR/normal/occlusion/emissive textures, node
hierarchy, skins, step/linear/cubic animations) and OBJ/MTL import, parametric primitives,
extruded/bevelled outline meshes and polygon triangulation with holes.
Project: FootageKind::Model, LayerSource::Model/Primitive, Layer::environment, Geometry and
Material Options builders, Environment light Source. Media probes and loads models
(FootageSource::model). Engine: layer.newModel, layer.new3dPrimitive/newPrimitive,
comp.renderer, layer.environment, material.set/reset/duplicateAssign/revealSource (stubs
replaced); File > Import and layer.addItem pick up models. Hand-written fixtures with
attribution sidecars.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Auto backend keeps comps with 3D layers on the CPU compositor (3D runs are
still CPU-composited; the GPU round-trip made them slower).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Region-of-interest frames render on the CPU path; the viewer keeps main's
frame drawing (Show Channel, exposure, ROI) and reads GPU-composited frames
back. Keeping frames as native egui-wgpu textures stays implemented behind
RenderSource::gpu_display (off).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
New L3 crate effectcraft-gpu: a wgpu compute backend for the per-frame
compositing walk (layer transforms with the CPU's nearest/bilinear/bicubic
sampling and minification pre-filter, motion-blur accumulation, track
mattes, Preserve Transparency, layer style passes and knockout, all 38
blend modes as a WGSL port of color::blend, 8/16 bpc clamp+quantise,
colour-space conversions). 3D runs, adjustment and wireframe layers run on
the CPU between GPU steps. GPU effects with the CPU semantics: Gaussian,
Fast Box and Directional Blur, Glow, Levels, Curves, Hue/Saturation, Tint,
Fill, Gradient Ramp, Fractal Noise, Drop Shadow, Brightness & Contrast,
Exposure, Invert, Transform (registry gpu badge from effects::GPU_EFFECTS).
render: Backend (Cpu/Gpu/Auto) in RenderOpts, the Accelerator trait and
Renderer::accel, GPU effect chains in the effect stack, hooks for the GPU
walk. Project setting gpu_acceleration (Mercury GPU Acceleration / Software
Only), render.backend command, file.projectSettings renderer. Session and
Render Queue exports carry the accelerator. CLI --gpu and bench --gpu.
Tests compare GPU vs CPU renders (blend modes x bit depths, transforms,
masks, mattes, motion blur, colour management, styles, collapse,
adjustment fallback, every GPU effect) and skip without an adapter.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- project.select/rename/move/setLabel/setComment engine commands (undoable; no folder into
itself).
- Drag items onto folders / the root, Enter or double-click the name to rename, double-click
the Comment cell to edit, label colour popup on the label column, Media Duration / File
Path / Comment columns shown or hidden from the header context menu, rendered comp/footage
thumbnails in the info header.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Type tool point/box text creation, double-click editing, caret and selection
in the viewer (viewer_text.rs), keyboard/IME/clipboard, box handles; engine
text.edit/endEdit/setSelection/moveCaret/insert/delete, layer.setText range,
caret insertion style, Paste Text and Match Formatting / Paste Text
Formatting Only (stubs removed); Character/Paragraph/Properties panels act
on the selection.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Composition viewer interaction parity with After Effects:
- Snapping (View > Snapping, the Tools bar checkbox, Cmd/Ctrl inverts while
dragging): layer edges, centres and anchor points, mask and shape-path
vertices, comp edges/centre, guides (Snap to Guides) and grid (Snap to
Grid), with highlighted target box / line / cross feedback. Pure maths in
engine::viewer (nearest target within tolerance, priority ties).
- Rulers (Cmd+R) with live pointer markers and a draggable zero point;
guides dragged out of the rulers, moved in the viewer, dragged off to
remove (view.moveGuide / view.removeGuide), lock respected; proportional
grid.
- Show Channel (RGB/Red/Green/Blue/Alpha/RGB Straight, Colorize), exposure
(+/- stops in linear light, reset), Take Snapshot (Shift+F5) with a stored
render and Show Snapshot (F5 held / button held), Fast Previews (Off,
Adaptive Resolution, Draft, Fast Draft, Wireframe), Resolution > Custom.
- Region of interest: drawn in the viewer; RenderOpts.roi renders only that
rectangle (crop of the full render, tested), Crop Comp to ROI uses it.
- Bottom bar in AE 2026 order ("136.1 %", "(Full)").
- Shape Pen (SHP-1): Pen on a shape layer / nothing selected draws Shape n
groups (Path 1, Stroke 1, Fill 1) via shape.newPath; the G slot cycles
Add / Delete / Convert Vertex and Mask Feather; mask.* vertex commands
work on shape paths; mask.insertVertex / mask.convertVertex; marquee
vertex selection, Alt-drag/click converts, double-click free transform
box (path.freeTransform on masks and shape paths).
- Motion paths (ANM-3): keyframe dots and spatial tangent handles, dragging
keys (keys.set) and tangents (keys.setSpatialTangents), parented layers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Frame Mix and Pixel Motion for footage and precomp layers when the layer's
Frame Blending switch and the comp's Enable Frame Blending are on and the
source time falls between source frames (rate conform, time stretch, time
remap). Exact frame positions from tick arithmetic. Pixel Motion is a
hierarchical block-matching optical flow (SAD search, sub-pixel parabola
fit, vector median) with a bidirectional warp-blend (raster::flow). Blended
footage frames are cached.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
8/16 bpc projects clamp and quantise layer pixels after source/masks and
every effect, and the comp after every layer (16 bpc = 0..32768); 32 bpc
keeps over-range values. Blend modes without HDR support clamp their inputs
in 32 bpc. Working space (sRGB, Rec. 709, Rec. 2020, Display P3; matrices
derived from the published primaries), footage colour profiles from stream
metadata or Interpret Footage, Linearize Working Space and Blend Colors Using
1.0 Gamma. Layer cache keys include the colour settings. Project panel depth
button: click cycles, Alt-click opens Project Settings.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>