Normalization
Stop blown-out latent channels before the VAE decodes them
- latent
- LATENT
You know the look: an image that's technically well-exposed but where one color family dominates - the sky is clipped, skin tones go muddy, everything leans the same way. That's often a latent channel that's spread too wide. The VAE decodes whatever range it's given, and if one channel is hogging the dynamic range, the decode reads as blown-out and flat. Normalization fixes it at the right place: it rescales the latent's channel ranges before the VAE decode, so the decoded image has room to breathe.
It's part of the Haoming02/comfyui-diffusion-cg ("Diffusion CG") pack. Where the pack's recenter nodes fix color during sampling, this node fixes the shape of the latent after sampling and before decode. Same family, different job, and the two compose nicely.
How it works
A latent is a tensor with 4 channels for SD 1.5 (3 for SDXL), and each channel has its own min/max range. This node scales each channel so its range approaches a target "normal" magnitude - from the source, it computes ratio = target_range / max(abs(min), abs(max)) and multiplies the channel by that (with a floor so it never shrinks a channel below ~0.99x). Channels that exploded are pulled back; channels that are too small are left alone rather than amplified into noise.
The subtle thing: this is a per-channel rescale, not a global brightness boost. That's why it reads as "vibrant and contrasty" instead of "brighter" - each channel is given its proper share of the range instead of letting one dominate.
The inputs that matter
- latent - wire from your KSampler's
LATENToutput (or anywhere in the latent path). - sdxl - a boolean. This is the version of the node that merged both models into one: flip it for SDXL (3 channels) or leave it off for SD 1.5 (4 channels). This is the one input a beginner actually has to think about - get it wrong and the node is normalizing the wrong channel count, which produces subtly wrong color instead of nothing.
Output: LATENT, into VAE Decode. That's the whole pipeline change - place it between KSampler and VAE Decode and you're done.
A note on versions
Normalization has had a long life across this pack's rewrites: it started as separate SD 1.5 / SDXL nodes, gained the sdxl toggle, and in the current v2 release its logic was folded into the single Diffusion CG node's normalization slider. If you install the pack today, you'll find Diffusion CG (which applies recenter + normalization during sampling) rather than this standalone latent node. Both approaches are valid; the standalone node is the one you want if you're normalizing an already-sampled latent (e.g. after a second-pass or img2img) without changing how sampling itself ran.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/Haoming02/comfyui-diffusion-cg
Restart ComfyUI. Zero dependencies, no model downloads.
Gotchas
- Set the
sdxltoggle correctly. Wrong channel count = wrong color. When in doubt, check which model your checkpoint is. - Normalization rescales, it doesn't recolor. If your image is cast (shifted hue) rather than blown-out, you want the pack's recenter functionality, not this node.
- Don't stack it with an aggressive normalization during sampling (the v2
Diffusion CGnormalizationslider) - double-normalizing a latent tends to flatten contrast instead of enhancing it.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| latent | LATENT | — | |
| sdxl | BOOLEAN | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| LATENT | LATENT | — |