⚛️FAI Dynamic Mask⚛️
Animated masks for video, minus the keyframe pain
- mask
- invert_mask
The name tells you most of it. FAI Dynamic Mask makes a mask that moves, and it hands you the whole thing as a sequence of frames instead of one static blob. In a normal image workflow you draw a mask and call it done; video is different, because usually you want the mask to change from frame to frame - a wipe, an iris close, a fade, a region that appears then disappears. That's the entire job of this node: pick a transition and a frame count, and it generates the whole timeline for you.
Where this actually shows up is audio-reactive video in ComfyUI. The pack's example workflow drives video generation with two-color masks - mask regions that shift over time to steer IP-Adapter and ControlNet conditioning. That's exactly what the wider ecosystem is doing with masks on video (the KB's AnimateDiff and IP-Adapter essays are the same story: per-frame conditioning is how you get a video to "do" something instead of just sitting there). This node is what you'd slot in before you'd otherwise hand-place masks on forty frames, which nobody wants to do by hand.
How it works is simple under the hood. For each of frame_count frames it computes progress t = frame / (frame_count - 1) and runs it through your chosen weight_type - linear, or the easing variants (ease_in / ease_out / ease_in_out), which give a slow-fast-slow feel instead of a robotic uniform sweep. Then it draws the shape_transition with OpenCV: circles, squares, diamonds (in and out), full-frame wipes in all four directions, and plain fades. The feather slider (0–1) blurs the edge with a Gaussian - at 0 you get a hard knife edge, and small values like 0.01–0.1 soften it into a dissolve rather than a visible mask cut.
The genuinely nice part is the output pair. You get mask and invert_mask - the exact inverse of the same sequence, computed for free. So one node feeds two opposing regions: drive a ControlNet with one while an IP-Adapter takes over the other, no separate invert node, no risk of the two masks drifting out of sync.
Inputs worth touching: shape_transition is the menu with 12 choices; weight_type changes the tempo; frame_count, width, and height should match your video generation settings or the masks won't line up with the latent you're feeding. And note the last frame lands on t=1.0, so a fade_in ends fully white - size your frame count against the effect you actually want.
One real gotcha: the node imports cv2 (OpenCV), but the pack's requirements.txt only lists torch, numpy, matplotlib. If it fails to import, pip install opencv-python fixes it - the README assumes you'll already have it from SaltAI_AudioViz, which the example workflows depend on anyway.
Install through ComfyUI Manager (search "FAI-Node"), or the manual route:
cd ComfyUI/custom_nodes
git clone https://github.com/alanhuang67/ComfyUI-FAI-Node
then restart ComfyUI. No model downloads - it's pure math on tensors, which is a nice change of pace from most video tooling.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| width | INT | 512 | — |
| height | INT | 512 | — |
| frame_count | INT | 30 | — |
| shape_transition | COMBO | 12 options: fade_in, fade_out, circle_out, circle_in, square_out, square_in, +6 | |
| feather | FLOAT | 0.000–1 | — |
| weight_type | COMBO | 4 options: linear, ease_in, ease_out, ease_in_out |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| mask | MASK | — |
| invert_mask | MASK | — |