DiffusionCG
The washed-out image fix that works while the sampler is still running
- model
- MODEL
If your images keep coming out hazy, washed-out, and that flat "medium gray" that's been the SD noise schedule's complaint since 2023, this is the node. DiffusionCG recenters and normalizes the latent while the sampler is still running - a port of Haoming02's SD WebUI Diffusion Color Grading extension, and it shares a pack with VectorscopeCC.
Two problems, two knobs:
- Drifting latent means. Every latent channel has an expected mean, roughly zero. As sampling goes on, that mean can wander - and a shifted mean decodes as a color cast or washed-out haze. Recentering subtracts each channel's mean (scaled by a strength) every step, pulling the latent back to center.
- Shrinking dynamic range. Values compress toward the middle as denoising progresses, which is low contrast in disguise. Normalization rescales each channel so its max absolute value maps to a fixed range, re-expanding the contrast.
Do both during sampling, and you fix the image before it's ever decoded - which is why this beats slapping a contrast curve on the finished PNG.
The inputs
- recenter_strength (0–1, default 0 = off) - how hard to pull each channel back to a zero mean.
- recenter_start_time / recenter_end_time - the window (fraction of the trajectory) in which recentering runs.
- normalize_start_time / normalize_end_time - the same window concept for normalization.
Here's the thing to notice about the defaults: normalization is on for the whole run (0 to 1), while recentering is off. So unlike its packmate, this node does something the instant you wire it in - you get the contrast back immediately. That's a feature, but it's also a trap: if your colors get too punchy or your blacks start clipping, that's normalization doing its thing, not your prompt. Set the normalize window to 0–0 to disable it.
How it works
Same CallbackManager as the rest of the pack (registered at priority 211 in the sampler loop). Each step it reads x0, the model's current clean prediction, and operates channel by channel. Recentering has a strength; normalization has no strength at all - inside its window it's all-or-nothing, so the window is the control. One detail worth knowing: the author hardcodes the SD1.5 scale factor when computing the dynamic range, with a source comment that the XL factor "is causing noise" - so it's tuned for SD-style latents, and it figures out your model's latent format from the model itself.
Wiring and install
One MODEL output, same as any model patch: checkpoint → DiffusionCG → KSampler. Works on both SD1.5 and SDXL. Pair it with VectorscopeCC from the same pack to add color grading on top.
Install once and you get all three nodes in the pack:
cd ComfyUI/custom_nodes
git clone https://github.com/pamparamm/ComfyUI-vectorscope-cc
Or ComfyUI Manager → search "ComfyUI Vectorscope CC". No model downloads, no extra dependencies.
Reach for it when generations look flat at higher CFG or with LoRAs that compress dynamic range. The one caveat: it works through the standard sampler callback path, so it won't do anything for samplers that bypass it - and remember that "washed out" sometimes means your model wants a better VAE, not another latent tweak.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| model | MODEL | — | |
| normalize_start_time | FLOAT | 0.000–1 | — |
| normalize_end_time | FLOAT | 1.000–1 | — |
| recenter_strength | FLOAT | 0.000–1 | — |
| recenter_start_time | FLOAT | 0.000–1 | — |
| recenter_end_time | FLOAT | 1.000–1 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| MODEL | MODEL | — |