Editor hardening, test baseline, CI validation, export fixes, and the blob-tracking layer#104
Merged
Merged
Conversation
…b-tracking groundwork - fix pre-existing biome lint errors (4 errors across app + package) - add first test suite: 75 tests over .lab parsing, parameter schema, timeline evaluation, composition math, blob tracker, inner effects - CI now lints, typechecks and tests the editor app, not just the package - .lab import: zod schema validation, consent prompt before imported custom-shader code runs, SVG raster resolution capped at 8192 - lazy-load export dialog and video muxers (-99.9 KB first-load JS) - close the video encoder on failed/cancelled exports; 30s timeout on stalled video texture loads - onRuntimeError no longer fires with null after successful init - renderer dedup: drift inventory + consolidation design (plans/006-artifacts) - drop localeCompare from per-frame parameter signatures - blob-tracking foundation: pure CPU tracker + inner-effects modules (unwired) Includes patch changesets for the two package changes.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This was referenced Jul 7, 2026
Closed
…, decorations) Wires the blob-tracking layer into the editor end to end: - BlobTrackingPass: 64x36 motion+luminance analysis with previous-frame feedback, non-blocking readRenderTargetPixelsAsync readback (live mode consumes last frame's buffer, never awaits), CPU tracker integration, 32-blob DataTexture table, aspect-correct square/circle/diamond SDF composite with shapeScale/invert, decorated and mask output modes (mask = white fills on black for the existing compositeMode machinery), CCTV decoration overlay (outlines, id+coordinate labels, straight or curved connecting lines, decaying trails) drawn on a CPU canvas and alpha-composited — never present in mask output, rewind reset, and a prepareForExportFrame that awaits the readback and steps the tracker once per distinct timestamp for deterministic exports - single inner-effect child pass (own switch over the 21 pass-backed effect types; no factory import to avoid a cycle) rendering into a private half-float target sampled inside shapes; child lifecycle (dispose on type change, size forwarding, param application through the tolerant JSON parser) - registration: EFFECT_LAYER_TYPES, layer registry params (Detection / Shapes / Inner Effect / Decorations groups; innerEffectParams hidden via the custom-shader sentinel pattern), pass factory, layer picker entry, shader-export unsupported list - properties sidebar: BlobInnerEffectSection renders the chosen inner effect's parameters against the hidden JSON param with visibleWhen support and no keyframe affordances (not keyframeable in v1) - inner-effect set now excludes blob-tracking itself (no recursive children) with a regression test
Package half of the blob-tracking feature: - blob-tracking-tracker.ts: verbatim copy of the editor's pure CPU tracker (self-contained module, no imports) - blob-tracking-inner-effects.ts: package flavor of the inner-effect set and tolerant JSON param parsing; no registry defaults — package passes apply their own per-parameter fallbacks in updateParams - blob-tracking-pass.ts: mirror of the editor pass adapted to the package runtime (tracker steps on the runtime clock's render time, no export-frame hook, createPipelinePlaceholder for half-float placeholders, decorations degrade to nothing without document) - registered in ShaderLabEffectLayerType, the pipeline's LayerPassNode union and createPass switch - README supported-layers list + inner-effect config docs in both READMEs; ShaderLabBlobInnerEffect helper type exported from index - minor changeset
Busy video content made every frame change the tracker state, which paid a full decoration-canvas redraw plus a full-resolution CanvasTexture re-upload (~8 MB/frame at 1080p) every frame — the webcam case felt fine only because quasi-static scenes rarely invalidated the overlay signature. Detection itself is fixed-cost (64x36 grid, 32-blob cap) and unaffected. - overlay canvas resolution capped at 960px wide (linear upscale; stroke widths and label sizes compensated so visuals are unchanged) - change signature quantized to overlay pixels, so sub-pixel jitter no longer counts as a change - live redraws rate-limited to ~30 Hz; the signature stays stale on skipped frames so the next eligible frame catches up; export frames bypass the throttle (prepareForExportFrame forces the redraw) to keep exports deterministic - trails draw every other history entry (visually equivalent, half the strokes) Applied identically to the editor pass and the package mirror.
This was referenced Jul 7, 2026
Closed
Closed
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Consolidates #92–#101 (issues #81, #84–#91) plus the full blob-tracking effect layer implementation.
Blob tracking (#91) — complete implementation, ready for in-browser testing
Editor (
feat: add blob-tracking effect layer):BlobTrackingPass: 64×36 motion+luminance analysis with previous-frame feedback, non-blockingreadRenderTargetPixelsAsyncreadback (live mode consumes last frame's buffer, one frame of latency by design), CPU tracker, 32-blob floatDataTexturetable, aspect-correct square/circle/diamond SDF composite withshapeScale/invert,outputMode: decorated | mask(mask = white fills on black for the existingcompositeMode: "mask"machinery), CCTV decoration overlay (outlines,#04 0.62,0.41labels, straight/curved connecting lines, decaying trails) on a CPU canvas — never present in mask output, rewind reset, andprepareForExportFramethat awaits the readback and steps once per distinct timestamp for deterministic exportsinnerEffectParamsJSON param (undo/change-detection for free, no keyframes in v1)Package (
feat: mirror the blob-tracking layer): tracker copied verbatim, pass adapted to the package runtime (steps on the runtime clock, decorations degrade withoutdocument), registered inShaderLabEffectLayerType+createPass,ShaderLabBlobInnerEffectexported, READMEs updated, minor changeset.Testing checklist (needs a WebGPU browser)
outputMode: mask+ layercompositeMode: mask→ stencils content below, no decorations in the mask (zoom in)screenUv.yflip inbuildEffectNode— flagged with a NOTE(orientation) commentOne deliberate gap: the picker preview image (
/examples/blob-tracking.webp) needs a screenshot of the working effect — entry ships without a preview until then.Everything else (unchanged from before)
.labimport hardening (zod + consent gate + SVG cap); lazy export dialog + muxers (−99.9 KB); encoder close on failed exports + video load timeout;onRuntimeError(null)fix; renderer dedup inventory + design;localeCompareperf fixVerification
bun test(76 pass),bun run typecheck:tsc, package typecheck,bun run lint,bun run build:runtime, fullbun run build, andbunx changeset status(minor bump) all pass.