Create Shape Mask
A circle, square, or triangle mask on demand (and animated)
- mask
- mask_inverted
Sometimes you don't need a fancy segmentation model to make a mask - you just need a circle in the middle of the frame, or a square in the corner. CreateShapeMask generates a plain geometric mask (circle, square, or triangle) at a size and position you set, and it'll even animate it growing over a batch of frames. It's the quick, procedural way to get a mask when the shape is simple and you know exactly where you want it.
Good for spotlight/vignette effects, blocking out a region for inpainting, feeding a shaped mask into attention or compositing, or - the fun one - an animated mask that expands frame by frame to drive a reveal or a growing region in a video.
How it works
You pick a shape and its dimensions, tell it where the center goes, and it renders that shape white on a black background at the frame size you specify. For animation, set frames above 1 and give grow a non-zero value: each frame the shape grows (or shrinks, with a negative value) by that amount, producing a mask batch that animates. The locations are center points, which is the intuitive way to place a shape - you're saying "put the middle of the circle here," not "start the bounding box here."
It's another of Kijai's small, no-dependency building blocks. Nothing to download, nothing to train - pure procedural geometry.
The inputs and outputs that matter
The ones you'll actually set:
shape(circle/square/triangle) - which shape.shape_width/shape_height(INT, default 128) - the size of the shape itself.location_x/location_y(INT, default 256) - the center of the shape, in pixels.frame_width/frame_height(INT, default 512) - the canvas size. Match this to the image you're masking against.
For animation:
frames(INT, default 1) - how many frames in the batch. Leave at 1 for a static mask.grow(INT, default 0) - pixels to grow the shape each frame. Positive expands, negative shrinks, 0 holds steady.
Outputs are mask (MASK) and mask_inverted (MASK) - the shape, and its inverse, so you can grab whichever polarity your downstream node wants without adding an invert node.
How to install it
ComfyUI Manager: search KJNodes for ComfyUI, install, restart. Manually:
cd ComfyUI/custom_nodes
git clone https://github.com/kijai/ComfyUI-KJNodes
pip install -r ComfyUI-KJNodes/requirements.txt
Restart and it's under KJNodes/masking. No models.
Common issues & troubleshooting
The mask doesn't line up with my image. frame_width/frame_height set the mask canvas - they need to match the resolution of the image you're masking. A 512×512 mask over a 1024×1024 image won't register where you expect. And remember location_x/y is the center, so to center a shape on a 512 canvas you use 256, not 0.
The shape is cut off at the edge. You placed the center too close to a border for the shape's size, so part of it falls off the canvas. Pull the location inward or shrink the shape.
My animation grows out of frame. With a positive grow over many frames, the shape eventually exceeds the canvas and clips. That's expected - size grow and frames so the final frame still fits, or let it clip on purpose if you want a full-frame reveal.
I need a soft edge. These shapes are hard-edged. For a feathered mask, run the output through a blur/grow-mask node downstream - CreateShapeMask makes the shape, softening is a separate step.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| shape | COMBO | circle | 3 options: circle, square, triangle |
| frames | INT | 11–4096 | — |
| location_x | INT | 2560–4096 | — |
| location_y | INT | 2560–4096 | — |
| grow | INT | 0-512–512 | — |
| frame_width | INT | 51216–4096 | — |
| frame_height | INT | 51216–4096 | — |
| shape_width | INT | 1288–4096 | — |
| shape_height | INT | 1288–4096 | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| mask | MASK | — |
| mask_inverted | MASK | — |