ComfyUI Node

Mask Gradient

Linear, radial, angular, no model required

By Code2Collapse·Created 7 months ago·Updated 2 days ago· 56
Mask Gradient
  • size_as
  • mask
  • mask
  • report
width512
height512
gradient_typelinear
angle0.0
center_x0.50
center_y0.50
start0.00
end1.00

What it is

A mask generator that makes ramps instead of selections. Linear fades, radial vignettes, angular wipes - the three shapes you end up needing constantly and which nobody wants to author in an image editor and re-import.

Where you actually use one:

  • Fade an effect off at the frame edge so a grade or a grain pass doesn't end in a hard line.
  • Vignette a render without round-tripping through a compositor.
  • A garbage matte - multiply a ramp into an existing matte so it dies off before it reaches something you don't want touched.
  • A wipe or transition between two branches of a graph, driven by the angular mode.

The KB's post-processing doc makes the broader point that these deterministic operations are the layer the ecosystem under-covers: "the operations are old and simple, but the node ecosystem around them is uneven". A gradient mask is the most old and most simple of all of them, and core ComfyUI still doesn't ship one.

How it works

The node builds a scalar field t across the frame, then remaps it from start to end:

  • linear projects pixel coordinates onto a direction vector set by angle, then normalises that projection so the ramp always spans the full frame - changing the angle rotates the fade without changing its contrast.
  • radial uses the distance from a normalised origin (center_x, center_y), normalised again by the largest distance in frame, so the outer corner lands at 1.
  • angular takes atan2 around that origin and adds the angle as a rotation offset, giving you a sweep.

t then maps linearly onto [start, end]. Swapping them (start 1, end 0) inverts the ramp, which is the cleanest way to flip a vignette - no invert toggle needed.

Inputs and outputs

Required: width, height (defaults 512×512 - these are only used when nothing is wired into size_as), gradient_type, angle, center_x, center_y, start, end.

Optional: size_as - connect an IMAGE and the output takes that image's dimensions, with width/height ignored (the report says so). And mask - an input matte that gets multiplied into the ramp, which is how you fade an existing mask off at the frame edge in one node.

Outputs: mask and report.

The one that bites people

The default output is 512×512. If you're compositing that against a 1024-wide render you'll get a mismatched mask, and whether downstream nodes resize it for you is up to them, not up to you. Either set width/height to your actual frame or wire size_as from the image you're working on. size_as is the honest option: it can't drift out of sync when you change resolution later.

Second thing: a mask in ComfyUI is [B,H,W] with values in 0–1, so a gradient mask is a multiplier, not a selection. Feeding a 50%-grey ramp into something that expects a binary region will give you a 50%-strength effect, which may be exactly what you want and may look like a bug.

Install

ComfyUI Manager → search "CustomNodePacks", or:

cd ComfyUI/custom_nodes
git clone https://github.com/Code2Collapse/ComfyUI-CustomNodePacks

Restart and check the console for the pack's [MEC] Loaded … line. Dependencies for the pack are opencv-python, scipy, safetensors - this node uses none of them, it's tier 1 (no model, no VRAM), and it's one of the fastest things in the pack because it's a meshgrid and two multiplies. As ever with this pack: read requirements.txt before running it, don't let it overwrite ComfyUI's torch.

Common issues

  • It's flat grey / entirely one value. start equals end. That's it, that's the whole bug.
  • The gradient is diagonal when you wanted vertical. angle is degrees; 0 is horizontal-right. Use 90 for top-to-bottom.
  • The radial centre isn't where you think. center_x and center_y are normalised 0–1, not pixels, and y goes down. On a non-square frame, "0.5, 0.5" is the middle of the image, not the middle of the longest side.
  • Angular mode looks offset. angle acts as a rotation offset in angular mode rather than a direction, so start with 0 and rotate from there.
CategoryMEC/Mask

Inputs (10)

NameTypeDefaultDescription
widthINT5124–16384Output width when size_as is not connected.
heightINT5124–16384Output height when size_as is not connected.
gradient_typeCOMBOlinearRamp shape — linear edge fade, radial vignette, or angular wipe.
angleFLOAT0.0-360–360Direction for linear, or rotation offset for angular ramps.
center_xFLOAT0.500–1Radial/angular origin, normalised 0–1 across the frame.
center_yFLOAT0.500–1Radial/angular origin, normalised 0–1 down the frame.
startFLOAT0.000–1Mask value at the ramp start (black end).
endFLOAT1.000–1Mask value at the ramp end (white end).
size_asoptIMAGEWhen connected, output size is taken from this image and width/height sliders are ignored.
maskoptMASKOptional matte to multiply into — fade a garbage matte off at the frame edge.

Outputs (2)

NameTypeDescription
maskMASK
reportSTRING