3D Motion Reference
Choreograph Video Motion With 3D Boxes Before You Even Type a Prompt
- Captured Video
If you've ever tried to make an image-to-video model do a specific camera move, you know the pain: you describe the motion in words, the model shrugs, and you get a wobble instead of a dolly. This node is a workaround from the "show, don't tell" school. It gives you a little interactive 3D viewport full of plain boxes. You move those boxes around like a stick-figure animator, hit Record, and it hands you a short video to feed into a video model as a motion reference.
It won't render your character or scene - it's purely a choreography tool. But a video model that takes a reference/driving clip follows shapes and camera movement far more faithfully than prose. Think of it as a motion storyboard you can actually hand to the model.
How it works
Under the hood it's a Three.js scene rendered right inside a custom widget (the canvas integration is borrowed from ComfyUI-qwenmultiangle, a decent pedigree). You've got a grid floor, a handful of boxes, and a camera. Drag to pan, Ctrl+drag to rotate the view, scroll to zoom. Click a box and you get standard transform gizmos - Move, Rotate, Scale - so you can pose your little abstract actors in 3D space. All those transforms are saved into the node's properties, so they survive a save and reload.
When you hit Record, it does something clever beyond capturing pixels:
- Grabs the WebGL canvas via
captureStream(24)and records a 24 fps WebM (VP9, falling back to VP8) for however many seconds you asked. - Uploads that file to ComfyUI's
input/directory as3d_motion_ref_record.webm. - Mutes every node that isn't a downstream descendant of this one, queues the prompt, and unmutes everything a second later. So unrelated branches of a big workflow don't all re-render just because you recorded a clip.
- The backend then loads that WebM and outputs it as a
VIDEOtype. Itsfingerprint_inputsappends the current time, so the node always re-runs and picks up your latest recording even when the inputs look identical - the kind of footgun a less careful author would have shipped.
The inputs that matter
There are only three, all on the widget:
- aspect_ratio -
16:9or9:16, default16:9. Reflows the viewport to match the shape of a landscape or portrait model. - recording_seconds - 4 to 15, default 7. How long the capture runs; match it to what your target model expects.
- num_assets - 1 to 10, default 1. How many boxes populate the scene. More lets you rough out multiple moving subjects, at the cost of a fiddlier arrangement.
The one output is Captured Video (VIDEO), and it's non-optional in practice: the Record button refuses to run unless that output is wired somewhere downstream, and it flags the node with an error explaining exactly that. Wire it into a video loader/preview, a VHS-style Save Video node, or whatever video model in your stack accepts a reference clip - Wan's I2V-family, Hunyuan Video, LTX and friends can all eat this as a driving input.
Installing it
The easy way is ComfyUI Manager - search for "ComfyUI-3D-motion-reference" and hit install. Or do it by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/arturitu/ComfyUI-3D-motion-reference
Then restart ComfyUI. That's the whole install: no requirements.txt, no model files to download, and the frontend ships prebuilt in js/, so you don't need Node.js on your box either. The Python side is just the node definition plus a tiny upload endpoint.
Where people get burned
This is a brand-new, tiny pack - essentially zero community footprint, so treat it as early-stage. The real friction points:
- You need a recent ComfyUI. The node is written against ComfyUI's V3 node API (
comfy_api.latest,ComfyExtension). On an older install the import will fail and the node won't even appear. If you're a few months behind on updates, update first. - It needs a browser. The viewport is a frontend widget, so this is a no-go for headless or API-only ComfyUI. You have to be looking at the UI to record.
- The output is a WebM at a fixed 24 fps. Your downstream workflow has to handle WebM (most video loaders do). If you're feeding frames into an image model, you'll need a video-to-frames node in between.
- Every new recording overwrites
3d_motion_ref_record.webmin your input folder. Make sure you've queued the run you want before recording the next take.
The bottom line
If you're a Wan or Hunyuan user who fights with motion prompts, this is a handy toy that costs nothing to try - no models, no deps, just a restart. It's rough around the edges and the author is clearly just getting started, but the "record in the widget, mute everything else, re-run" loop is the right idea, and transform persistence means your poses survive a reboot. Worth a watch.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| aspect_ratio | COMBO | 16:9 | 2 options: 16:9, 9:16 |
| recording_seconds | INT | 74–15 | Duration of the captured video recording in seconds (4-15) |
| num_assets | INT | 11–10 | Number of 3D boxes to render in the scene (1-10) |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| Captured Video | VIDEO | — |