RedNode Refine Crop
Cut a face out at real resolution and refine it with any sampler
- image
- mask
- vae
- latent
- crop
A face that fills seventy pixels of a 1024px frame is going to be a smear no matter how good your checkpoint is - the latent simply has no budget to spend there. The fix has always been the same: crop the region, upscale it, run a fresh sampling pass on it, paste it back. That's the entire detailer loop, and RedNode Refine Crop is the crop-and-encode half of it, deliberately built to hand off to any sampler - the brief even suggests pairing it with KreaPhoton on Krea 2.
Unlike Impact Pack's FaceDetailer, which hides the whole loop inside one node, this is the honest, open version: you see the crop, you control the sampler, you decide the prompt. That's more work, and it's also the point. When the automatic detailer's default prompt or denoise isn't doing what you need, having the pieces exposed lets you fix the actual problem instead of fighting a black box.
How it works
Four steps, classic and unglamorous:
- Take the mask (face, hands, eyes - from a SAM3 face mask, a painted MaskEditor mask, or any MASK output).
- Cut the masked region out with extra context around it.
- Upscale the crop so its long side reaches a resolution the model can actually resolve.
- Encode it to a latent for sampling.
The output latent feeds any sampler's latent input. Whatever that sampler produces gets VAEd-decoded and handed to RedNode Refine Paste, which composites it back through the feathered mask - pixels outside the mask are untouched.
The inputs that matter
image- the frame to refine.mask- the region. Outside it, the paste is a no-op.vae- for the encode.context_margin- extra context around the mask's bounding box, as a fraction of its size. 0.5 means 50% on each side. This is the one beginners skip and then wonder why the refined face doesn't match the lighting and skin of the frame: the sampler needs surroundings to blend against. A bare face crop floats.target_px- the crop's long side is scaled up to this before sampling; 1024 is the sensible default, 0 keeps native size. It never downscales a crop that's already larger.feather- the paste-edge softness in pixels, applied to the mask at paste time. Too small and you see a seam; too big and the refinement bleeds.
Outputs: latent (for the sampler) and crop (the RN_CROP handle that Refine Paste needs to put it back).
Installing it
Part of RedNode Studio:
git clone https://github.com/RedNodeAI/ComfyUI-RedNodeStudio.git ComfyUI/custom_nodes/ComfyUI-RedNodeStudio
Restart ComfyUI, or search RedNode Studio in ComfyUI Manager. No pip dependencies or model downloads for the node itself - you supply the mask from whatever detector you already use (SAM3, YOLO face models, MaskEditor).
The traps
The context_margin default of 0.5 is a floor, not a target - tight face crops around hair or glasses usually want more, so the sampler has something to blend the new detail into. And keep in mind the encode/decode cycle is exactly the thing that shifts colour and greys out face patches in detailer workflows; a feather that's too small makes that seam visible, so feather is your first knob when a refined face looks "pasted on". Last, this is a loop you run on purpose: if you're chasing a same-seed result, every piece of the chain - the mask, the sampler, the denoise - has to be deterministic, or the detail pass re-rolls the lottery it's supposed to be fixing.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| mask | MASK | the region to refine (face/hands/eyes) — SAM3 face mask, MaskEditor paint, or any MASK output. Pixels outside it are untouched by the paste. | |
| vae | VAE | — | |
| context_margin | FLOAT | 0.500–2 | extra context around the mask's bounding box, as a fraction of its size (0.5 = 50% on each side) — the sampler needs surroundings to blend lighting/skin |
| target_px | INT | 10240–4096 | upscale the crop so its long side reaches this before sampling (the whole point of a detailer: more pixels for the face). Never downscales a crop that is already larger. 0 = keep native size. |
| feather | INT | 80–64 | paste-edge softness in image pixels (applied to the mask at paste time) |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| latent | LATENT | — |
| crop | RN_CROP | — |