Skip to content

Blender void#74

Open
TheTechromancer wants to merge 5 commits into
devfrom
blender-void
Open

Blender void#74
TheTechromancer wants to merge 5 commits into
devfrom
blender-void

Conversation

@TheTechromancer

Copy link
Copy Markdown
Member

Blender void

Adds a new Blender void layer that shows a live view of a Blender session — with a transparent background, so you can paint behind and around the 3D scene and treat Blender as just another layer. It pairs with a companion Blender extension (darkly-art/blender-extension) that captures the 3D viewport (or a camera POV), encodes alpha-carrying PNG frames, and serves them over a localhost HTTP server as a single chunked response of length-prefixed frames ([4-byte big-endian length][image bytes]).

Rust core

  • gpu/voids/blender.rs — the new void, registered through the standard modular register() mechanism. It is a thin config over the shared video_stream_void machinery (the same base as the camera and screenshare voids), declaring freeze, frame_divisor, and a new url string param. url is document-persisted state the frontend reads to know where to connect (default http://localhost:8765/stream); the Rust void never interprets it.
  • CaptureKind::Stream — a third capture kind alongside Camera / Display, serialized to the frontend as "stream" so the app knows to source frames via HTTP fetch rather than a MediaDevices API.
  • Passthrough params in video_stream_void — the shared machinery now keeps a param_snapshot of every param in schema order, so params it doesn't model (like url) round-trip through from_paramsparam_values (save/load) and update_params (the properties panel) instead of being silently regenerated from their defaults. Covered by a regression test (passthrough_param_round_trips) plus unit tests on the void's registration, params, and default transform.

Frontend

  • lib/frameSource.ts — new abstract FrameSource base extracted from MediaStreamSource, owning the per-tick lifecycle every external-frame void shares: the visible / frozen / frame-divisor / has-new-frame gate, off-thread createImageBitmap decode (with the document-resolution downscale cap), and the uploadVoidExternalImage GPU upload. Subclasses only supply where the frame comes from.
  • lib/httpStreamSource.ts — the Blender-side subclass. It fetches the stream URL, pumps the response body in the background, and reassembles complete length-prefixed frames independent of HTTP chunk boundaries. Frames decode with premultiplyAlpha: 'none' to preserve the straight alpha the add-on emits, and the blob carries no MIME type — createImageBitmap content-sniffs, so the add-on can switch codecs without a frontend change. A change-driven hasFrameReady gate means a static Blender scene drives zero decode and zero GPU work. Reconnect-on-url-change, supersede-in-flight-connection, and clean disconnect handling (with human-readable errors like "Is the add-on running?") are all covered by unit tests (httpStreamSource.test.ts).
  • lib/mediaStreamSource.ts — refactored down to a FrameSource subclass that only supplies the live <video> frame and the MediaStream lifecycle; all duplicated tick/decode/upload logic moved into the base.
  • state/app.svelte.ts — the media-stream registry generalized to a FrameSource registry (streamSources, startStreamSource, stopStreamSource, …). stream voids connect immediately on creation — no gesture or permission gate is needed for a localhost HTTP stream — while camera/screenshare keep their in-gesture acquisition path. The layer-tree reconciler additionally pushes url changes to a live source, and the existing reap/freeze/visibility/divisor plumbing applies unchanged.
  • UI — the void picker skips MediaStream acquisition for stream voids; VoidProperties gains a string-param text input (used for url) and a per-kind connect verb ("Connect to Blender" alongside "Resume camera" / "Resume screen share"), with disconnect errors surfaced in the same notice camera/screenshare use.

Misc

  • README "Features & Roadmap": added `[x] Blender stream void.

The companion Blender extension itself lives in its own repository and is not part of this diff.

@codecov

codecov Bot commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.75281% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
crates/darkly/src/gpu/video_stream_void.rs 96.77% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant