Vignette
The cheapest trick for making an AI render look shot rather than generated
- image
- image
- vignette_mask
There's a thread from December 2025 where someone works out why their AI video looks fake, and the top replies land on the same stack: motion blur, camera shake, grain, a touch of chromatic aberration - and vignetting. Vignetting is in there because real lenses fall off toward the corners, and because it's free.
This is that operation, as a node. No model, no sampler, no second pass through the diffusion model. It's a multiply, and it takes microseconds, which is the entire argument for doing it here instead of re-rolling a generation because the frame "looks too clean."
How the falloff works
Where most vignette implementations use a smoothstep or a radial gradient, this one is photometric. It builds a normalised radius from the optical centre with an aspect-ratio correction on the X axis, scales it by feather, then applies a cosine-power falloff: cos(r · π/2) raised to power. At the centre you get 1.0, at normalised radius 1 you get 0.
The result is blended by strength - 1 - strength · (1 - mask) - so strength is the corner darkening and power is the shape of the curve. power = 2.0 is the natural, roughly cos⁴ look a real lens gives you. Higher values harden the edge until it's a stylistic spotlight rather than a lens artefact.
RGB channels get multiplied by the falloff. Alpha is deliberately untouched, so the node is safe in a matte pipeline. The final composite is image · vignette · tint_map, where the tint only scales the dark areas.
Inputs
Six required, and four of them you'll set once:
image- works on linear or display-encoded input, since it's a multiply either way.strength- 0 to 1, default 0.5.1is corners gone to full black;0is a no-op.power- 0.5 to 8, default 2.center_x/center_y- 0–1, default 0.5/0.5. Off-centre it reads as a stylised grade; on-centre it reads as a lens.feather- 0.1 to 4, default 1.> 1pushes the falloff inward, so the darkening starts further from the corners. This is the control people miss, and it's the one that decides whether the result looks like a lens or like a border.
Optional and genuinely useful: tint_r / tint_g / tint_b (0–2, default 1.0 each) multiply the vignetted dark regions only. Nudging blue up past 1.0 gives you cool shadow edges - the noir / thriller look, and a period-film warm-centre-cool-edges feel comes from warm centre values with a cooler corner tint.
Two outputs:
image- the vignetted picture.vignette_mask- the falloff itself as a grayscale IMAGE in [0,1]. This is the underrated half. Multiply a grain pass, a blur or a grade by it and they'll fade with the falloff instead of sitting flat over the corners, which is how you get the effect to look optical rather than pasted on.
Install
ComfyUI Manager → search Radiance → install → restart → refresh. Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/fxtd-studios/radiance.git
cd radiance
python -m pip install -r requirements.txt
Windows portable users: use python_embeded\python.exe for pip. This node itself is pure tensor maths, but the pack wants OpenImageIO and OpenColorIO installed in ComfyUI's Python environment - install.py takes care of that, and a missing library surfaces as an import error in the console at startup.
Where people get burned
Stacking vignettes. If the checkpoint already bakes in a heavy vignette (plenty of the cinematic-looking fine-tunes do), adding 0.5 on top turns into a keyhole. Check the corners before you reach for this.
Forgetting it's baked once you write. It's an ordinary image operation, so a 16-bit EXR downstream keeps it, and so does an 8-bit PNG. There's no "vignette as metadata" here.
Expecting the mask to be an alpha. vignette_mask is a 3-channel grayscale IMAGE, not a MASK. Wire it into another IMAGE input (a multiply, a blur, a grade) - not into something that wants a MASK tensor, unless you convert it first.
Using it as a crop substitute. The darkening doesn't hide composition mistakes; it just dims them. Crop or reframe first if the edges are the actual problem.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | Image to vignette. RGB is multiplied by the falloff, so linear and display-encoded images both work; alpha is untouched. | |
| strength | FLOAT | 0.500–1 | Vignette intensity at corners. 0=no effect, 1=full black. |
| power | FLOAT | 2.00.5–8 | Falloff exponent. 2.0 = natural cos⁴ approximation. Higher = harder edge. |
| center_x | FLOAT | 0.500–1 | Horizontal center of the vignette (0 = left, 1 = right). |
| center_y | FLOAT | 0.500–1 | Vertical center of the vignette (0 = top, 1 = bottom). |
| feather | FLOAT | 1.000.1–4 | Radial feather: scales the normalized radius. >1 = pushes falloff inward. |
| tint_ropt | FLOAT | 1.000–2 | Red multiplier for vignetted (dark) areas. 1.0=neutral. |
| tint_gopt | FLOAT | 1.000–2 | Green channel multiplier for vignette tint. 1.0 = neutral. |
| tint_bopt | FLOAT | 1.000–2 | Blue multiplier for vignetted areas. >1 = cool shadow edges. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | Vignetted image. |
| vignette_mask | IMAGE | Grayscale vignette mask [0,1] — wire to downstream grades or multiply nodes. |