Nodes/ComfyUI-Foveated_Diffusion/Foveation Mask (FovDiff)
ComfyUI Node

Foveation Mask (FovDiff)

Point the fovea before you spend the tokens

By ruwwww·Created 2 months ago·Updated 2 months ago· 1
Foveation Mask (FovDiff)
  • latent
  • foveation_mask
mask_shapecircular
center_x0.00
center_y0.00
radius0.30

The fovea is the part of your retina that's actually sharp; everything else is peripheral detail your brain fakes in. Foveated Diffusion does the same to image generation - it keeps a small region at full resolution and runs the rest at a fraction of the tokens. This node is the part where you decide where that sharp region sits. Get it right and you get the 2–4× speedup the technique is known for; get it wrong and you've burned quality on the one part of the image that matters.

FoveationMask is the first node in the ruwwww/ComfyUI-Foveated_Diffusion pack for a reason. On its own it does exactly nothing to your image - it just computes a binary mask in latent (token-grid) space, marks the high-resolution region, and hands that mask to FoveatedKSampler. Think of it as the map, not the trip. The mask is a real output type (FOVEATION_MASK), not a latent, so wire it straight into the sampler and, if you're sane, into FoveationMaskPreview first so you can see what you're about to do.

The inputs that matter

Four of them, and only two are actually interesting:

  • center_x / center_y - normalized gaze position, −1 to +1. 0,0 is dead center; +1/-1 puts the sharp region at the right/bottom edge. This is the "foveation" idea in action: your subject is where the model should spend its tokens.
  • radius - foveal radius as a fraction of image half-width. The default 0.30 is the paper's own setting, and the README's own demo treats 0.60 as the "gentle" end. Smaller radius = bigger speedup, and a harder bill when the subject isn't actually centered there.
  • mask_shape - circular, square, or ellipse. Circular matches the paper; square is block-friendlier and often produces slightly cleaner edges with the LR blocks; ellipse exists for portrait-ish crops. All three are fine to try.

The latent input is worth understanding even though you don't tune it: the mask is generated in token-grid space from your latent, which is why the mask and latent shapes must match when they hit the sampler. Feed it the same EmptyLatentImage latent that goes into FoveatedKSampler, or you'll hit a hard shape-mismatch error later.

Where people get burned

The trap is psychological, not mechanical: because the mask decides what's high-res, the periphery is deliberately degraded ("prioritized distortion" is literally the paper's title). A small radius with a subject drifting off-center means the face - the thing everyone looks at first - gets the low-res treatment. If the result looks soft around your subject, the fix is almost always a bigger radius or a center_x/y that actually tracks the subject, not a sampler change.

This technique is also new enough that the community has barely touched it - as of mid-2026 there's exactly one announcement thread about foveated diffusion and almost nobody reporting field experience, so your own eyes are the debugging tool. Spend the ten seconds with FoveationMaskPreview before you run a full batch.

Install and the workflow

Install the pack once via ComfyUI Manager (search "FovDiff" or "Foveated") or:

cd ComfyUI/custom_nodes
git clone https://github.com/ruwwww/ComfyUI-Foveated_Diffusion

then restart ComfyUI. The pack needs ComfyUI with FLUX.2 Klein support and PyTorch 2.0+, and it's Klein-only - don't feed it an SDXL or Flux.1 checkpoint.

From there the chain is: LoadFoveatedLoRAFoveationMaskFoveatedKSampler, with this node sitting between the empty latent and the sampler. One light warning: the pack is research-fresh and moving - if the mask or sampler throws a shape error after an update, the README's quick-start graph is the fastest way to see what changed.

Categoryfoveated_diffusion

Inputs (5)

NameTypeDefaultDescription
latentLATENT
mask_shapeCOMBOcircular3 options: circular, square, ellipse
center_xFLOAT0.00-1–1Horizontal gaze position. -1=left, +1=right, 0=center.
center_yFLOAT0.00-1–1Vertical gaze position. -1=top, +1=bottom, 0=center.
radiusFLOAT0.300.05–1Foveal radius as fraction of image half-width. 0.30 = ~30% of image width is high-res.

Outputs (1)

NameTypeDescription
foveation_maskFOVEATION_MASK