Recenter
Keep your KSampler, fix the color cast anyway
- latent
- LATENT
The first version of this pack made you replace your KSampler with a special one. That worked, but it meant re-wiring every workflow that wanted the effect. Recenter is the smarter second pass at the same idea: it's a tiny latent-in/latent-out node you drop between Empty Latent and your existing KSampler. It doesn't replace anything. It just sets a hook that makes your normal sampling recenter the latent channels - pulling color back to neutral while the image is drawn, not after.
How it works
When you place Recenter in a workflow, it stores the target channel means and an effect strength in a global, and quietly wraps ComfyUI's sampling functions (comfy.sample.sample and the custom-sampler variant). From then on, every sampling pass runs through the wrapped version, and at each step each of the 4 latent channels gets nudged:
x[channel] += (target_mean[channel] - x[channel].mean()) * strength
The output of the Recenter node itself is just the latent you put in - the work happens inside whatever KSampler follows it. That's the elegant part: your sampler, your scheduler, your CFG, all unchanged.
The inputs that matter
- latent - wire from
Empty Latent(or anything feeding a KSampler). - strength - 0 to 1, default 0. The master volume. Zero means "don't touch anything."
- C, M, Y, K - target means for the 4 channels, all default 0 in this version. The node maps them internally as
[-K, -M, C, Y]. Think of them as "where should each channel's mean sit" - set them all to 0 for a neutral pull, or bias individual channels to steer color by hand.
Output: LATENT, feeding your KSampler's latent_image as usual.
The thing to know: the effect is global
This is the catch, and the author's own issue tracker has the stories to prove it. Recenter sets module-level state, so once it's in a workflow, every sampling pass in that run gets recentered - including a hires-fix second pass, which usually isn't what you want. There's no per-sampler scoping. The practical consequences:
- Add another Recenter with
strength0 later in the graph to "turn it off" for subsequent passes. - The pack auto-resets the global when you run a workflow that contains no Recenter node, so a fresh graph won't inherit the old settings - but partial reruns are the trap: if ComfyUI only re-executes part of the graph (cached nodes above a Recenter don't re-run), the global can stay stuck on stale values. The classic symptom is a workflow that changes color for no reason after you edit an unrelated node.
- Because it hooks
sample/sample_custom, not every sampler cooperates. The README's known issue - "does not work with certain samplers" - bites here, with LCM/Turbo-style low-step samplers the usual suspects.
A note on versions
Recenter comes from the middle era of the pack. The current v2 rewrite replaces it with Diffusion CG, which applies recenter (toward 0) plus normalization in one node with the same global-state trade-off, and pairs it with Disable CG as the reset. If you install the pack today and only find those two nodes, that's the redesign doing its thing.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/Haoming02/comfyui-diffusion-cg
Restart ComfyUI. Zero dependencies, no model downloads.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| latent | LATENT | — | |
| strength | FLOAT | 0.000–1 | — |
| C | FLOAT | 0.00-1–1 | — |
| M | FLOAT | 0.00-1–1 | — |
| Y | FLOAT | 0.00-1–1 | — |
| K | FLOAT | 0.00-1–1 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| LATENT | LATENT | — |