Right-click now creates a transient ZoomSceneElement at z-index 1 whose pixels are a genuine 2x magnified sample of the backdrop (live capture under art), composited into stream/recording like any layer while the output crop stays the tier. All shapes are centered on the click and clamped to frame; healed on load/scene-create, never persisted, hidden from the layers list + element template (IsZoomLayer). BuildCompositorOptions is now internal = always tier crop (test seam). ZoomFrameBuilder is a pure static sampler (box/2 window centered on the box center, single-slot cache) proven by a banded-backdrop test; LayerReorderPersistenceTests drag resolves rows by item since the collapsed zoom row shifts container indices. Also books TASK 51 (webcam background Remove + Blur) and syncs memory docs (HANDOFF, MyMistakes, indexes). Full suite: 405 passed, 0 warnings.
5.4 KiB
TASK 51 — Webcam background effects: Remove + Blur (v1 requirement)
Catalog:
TASKS.md— status and requirements live here. Booked 2026-10-08 by creator ruling — "we're doing the bg removal and blur for v1 - book it, Danno". This reverses the 2026-10-05 "background removal: out of product" exclusion (TASK 3 item 19).
Status: ☐ Booked — v1 requirement. Queued behind the zoom build (current in-flight work unit).
Goal: per-webcam Background Remove and Background Blur on the live webcam layer, selected per element in its properties panel, composited into stream + recording like any other layer. No external downloads, no hardware requirement, works on any machine. Replacement backgrounds are free via layers — drop any element behind the webcam.
Why this is now IN (and what changed)
The 2026-10-05 exclusion was based on: an in-app AI model = a runtime, a GPU/driver matrix, per-scene lighting tuning, and "a vcam app does it free." The ruling is reversed because the delivery shape changed:
- Bundled small ONNX model (~2–5 MB) — MediaPipe Selfie-Segmentation family — shipped in the installer/fixture (TASK 48 MSIX), executed by onnxruntime (CPU default; DirectML optional later). No NVIDIA SDK, no GPU requirement, no per-client download.
- Quality reality (creator): a 720p webcam displays at ~15% of a 1080p frame — premium segmentation quality is invisible at that size; commodity class is sufficient.
- ⛔ Ruled out: NVIDIA Video Effects SDK (VFX / Maxine, AI Green Screen + Background Blur). Works on RTX 2000+/R570+ only, and needs a ~1 GB user-side redistributable on first use. Creator: "I don't think I'm putting a 1gb download requirement on a client box."
Constraints — non-negotiable
- No external download at runtime. Model ships in the installer. (Store policy 10.2.2 — same posture as the ffmpeg bundling in TASK 48 item 1.)
- No hardware requirement. CPU path must work; DirectML is an optional accelerator.
- Per-element (Meld-style), not global. Each webcam element carries its own effect.
- No feature gating. Works for free users; only the branding flash is paid.
- Scene change / webcam add/remove must not crash or stall the pump — a failing model run skips to passthrough, never drops the layer.
Out of scope for v1 (same engine later)
- ❌ "Remove chair"-style object selection / quality tiers — not a picker engine
- ❌ Super resolution / denoise / prettify passes
- ❌ Virtual camera output — permanently out of product (no vcam)
1. ☐ Engine
- ☐ Bundle an ONNX person-segmentation model (MediaPipe Selfie-Segmentation class, ~2–5 MB)
into the app (csproj copy like
ffmpeg/, or as anAsset). Verify license + THIRD-PARTY notices (TASK 36 item 6 gate). - ☐
onnxruntimevia NuGet. CPU EP by default; optionally DirectML EP later. Failing EP init → passthrough, log once, never throw from the pump. - ☐ Blur = separable in-app blur (box/gaussian) over the masked background region. No model needed for blur once the mask exists.
- ☐ Remove = alpha 0 outside the person region. The compositor already alpha-blends per
element (
SceneCompositor, source-over) — no compositor change expected. - ☐ Feed the VideoFrame seam (
Services/VideoFrame.csdoc explicitly anticipates "every future capture source (screen, background-removed webcam) feeds the same seam"): the frame handed to BOTH the preview bitmap path and the compositor's_cameraManager.GetLatestFrameis the processed frame. One processing point, two consumers.
2. ☐ Config surface + persistence
- ☐
WebcamSceneConfiggainsBackgroundEffect(None | Remove | Blur) +Strength. - ☐ Persist via the existing
WebcamSceneConfigtable path inLayoutStore.Save.cs/Load.cs(new columns + migration). FollowLayoutStore.Migrations.csconventions. - ☐ Properties panel: effect dropdown + strength slider, per webcam element.
- ☐ Replace-background affordance: none in v1 — the creator drops any layer behind the webcam. Effect preview must not obscure the fact that layers below still show through.
3. ☐ Test seam (Good Dog — one integration test per unit)
- ☐ Model-runner interface seam (like
CameraEnumeratorOverride) so tests inject a fake segmenter — no real ONNX inference in the test suite. - ☐ Assert the processed frame reaches both consumers (preview bitmap + compositor frame).
- ☐
None= byte-identical passthrough of the raw frame. - ☐
Remove= alpha 0 outside person rect;Blur= background region blurred, person sharp. - ☐ Config → persistence roundtrip (per webcam element).
- ☐ Engine failure → passthrough + single log, layer never dropped.
- ☐ Real inference: manual on the creator's box (camera + lighting), not in CI.
4. ☐ Sequencing
- ☐ Separate work unit AFTER the zoom build. This file is booked + scoped; do not co-commit it with the zoom work.
Related (not duplicated here)
task-48-distribution-msix.md— the model ships in the MSIX; bundled-binary posture established by the ffmpeg work.TASKS.mdWebcam cadence section — the "⛔ no background removal" line is superseded by this ruling; the judder/compositor cost work is unaffected and still heads its lane.research-store-certification.md— 11.12/10.2.2 posture; nothing here sends data off-box.