Roto Mask
Bezier Masks That Track Time
- video
- mask
Every serious video pipeline eventually needs the word nobody likes: rotoscoping. Drawing a mask frame-by-frame around a moving subject is where compositing projects go to die. ComfyTV's Roto Mask stage is its attempt to make the miserable part at least convenient - a bezier roto tool living right inside a node, outputting a mask video that flows into whatever keying or compositing stage comes next.
Under ComfyTV/VideoFX, it's a different animal from the promptable/SAM masking the ComfyUI ecosystem is full of. Those find a region automatically; this one is manual and precise. You draw a spline directly on the node's video preview - the shape_keys field carries your points as time-stamped JSON ([{t, points:[{x,y,lx,ly,rx,ry}]}], where each point carries its bezier handles lx,ly,rx,ry), so the shape can evolve over the clip rather than being one static cutout. It's roto the way editors expect it: shape per keyframe, not per frame.
The controls
The surface is small on purpose:
feather- edge softness in pixels, 0–200. A little goes a long way; you want a soft edge so the mask doesn't read as a hard matte line.invert- flip the matte when you want everything except the drawn shape (e.g. you traced a background element to hold it out).shape_keys- the geometry JSON. It's hidden plumbing driven by the drawing UI, but it's also the answer when the node won't run.
The video input is optional; the output is a mask (a COMFYTV_VIDEO - the grayscale matte of your shape over the clip's duration), which you wire into a KeyMix, a chroma-key despill, or a Compose stage to actually composite on top of it. There's no auto-tracking in this node - if your subject is a car driving toward camera, you're keyframing the spline by hand - though the pack's sibling Mask Propagate stage (optical-flow propagation) exists for exactly that follow-up.
Install
It's part of the ComfyTV pack, installed all at once:
cd ComfyUI/custom_nodes
git clone https://github.com/jtydhr88/ComfyTV
Restart ComfyUI (backend restart, not a refresh) and it appears under ComfyTV → VideoFX. Or use ComfyUI Manager and search "ComfyTV". On ComfyUI Desktop or macOS, grab the running instance's absolute path from the startup log before cloning - the relative cd is how people end up with a successful clone and no nodes. No model downloads, no extra Python deps: the roto math is pure torch/numpy.
Troubleshooting
- "Roto Mask: draw a shape (3+ points) on the node first." This is the node's own error and it's exactly what it says - the
shape_keysJSON is empty or has fewer than 3 points. Go draw a proper closed-ish spline on the preview; a two-point line isn't a mask. - Mask edges look jagged or aliased. That's
featherat 0. Even 3–5px softens the matte massively and makes the composite believable. - Mask is covering the wrong thing. Check
invert- tracing the background and forgetting to invert is the classic mistake.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| force_run_token | INT | 00–2147483647 | Internal — bumped on Run to invalidate ComfyUI's input cache. |
| project_id | STRING | Internal — populated by the projectStore on the frontend. | |
| parent_output_id | INT | 00–2147483647 | Internal — lineage parent set by spawn handlers on the frontend. |
| shape_keys | STRING | JSON [{t, points:[{x,y,lx,ly,rx,ry}]}] | |
| feather | FLOAT | 00–200 | — |
| invert | BOOLEAN | false | — |
| videoopt | COMFYTV_VIDEO | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| mask | COMFYTV_VIDEO | — |