C2C VAE Quality Decode (HDR)
The Wan decode node that fixes banding and flicker — fp32 precision and spatial-only tiling, one swap
- samples
- vae
- IMAGE
If you generate Wan video in ComfyUI and the frames come out with banding in gradients or a subtle flicker across time, the usual suspect isn't the sampler - it's the VAE decode. Wan's VAE is trained and behaves noticeably better when decoded in fp32, and tiling the decode wrong can make each tile flicker independently. C2CVAEQualityDecode is a drop-in replacement for the standard VAE Decode node that handles both: it forces fp32, uses spatial-only tiling so temporal coherence is preserved, and can optionally apply ACES tonemapping on the way out for that HDR-ish finish.
It's aimed squarely at Wan video, but it's a standard LATENT + VAE in, IMAGE out node, so it slots anywhere you currently have a VAE Decode. The community's own guidance on Wan (from the corpus) already points at sigma shifts and careful decode settings for flicker; this node automates the decode side of that fight.
How it works
The implementation in nodes/hdr_color_science.py wraps the normal VAE decode with quality upgrades. With force_fp32 on (the default), it converts the latent to float32 and - if it can reach the VAE's first-stage model - temporarily moves the VAE itself to fp32, decodes, then restores the original dtype so you don't leak a half-converted model into the rest of your graph. When a tile_size is set on a 5D (video) latent, it hands off to a spatial-tiled decode that tiles only the spatial dimensions, leaving the temporal axis intact - the point being that temporal tiling is what causes frame-to-frame flicker. If that tiled path throws for any reason, it logs a warning and falls back to a standard decode instead of crashing your run. With apply_aces on, it finishes with the ACES filmic curve and exposure before encoding back to sRGB.
The inputs
- samples - your
LATENTfrom the sampler. - vae - the
VAE. - force_fp32 (true) - leave on. This is the whole quality win.
- tile_size (0) - spatial tile size. 0 = auto/no tiling; the tooltip recommends 256+ for 1080p output, i.e. when the decode would otherwise OOM on a big frame.
- apply_aces (false) - filmic tonemapping after decode.
- exposure (1.0) - only used when ACES is on.
Output is a single IMAGE.
Installing it
Part of Code2Collapse/ComfyUI-CustomNodePacks. ComfyUI Manager → search "CustomNodePacks", or:
cd ComfyUI/custom_nodes
git clone https://github.com/Code2Collapse/ComfyUI-CustomNodePacks.git
Restart ComfyUI. No extra model downloads and no extra pip packages for the core path - fp32 decode and ACES are pure torch. (Skip the pack root's blanket pip install -r requirements.txt; install only what you're missing.)
Gotchas
Two things to know before you adopt it. First, fp32 decode is slower and hungrier than the fp16 default - that's the price of the quality, and it's why tile_size exists. On a big 720p+ video, set a tile size rather than letting the whole frame decode in one shot, or you may trade banding for an OOM. Second, the ACES step is off by default for a reason: only enable it if you actually want the filmic look, because once it's baked into the decoded frames it's hard to undo. And don't be surprised if your first 5D latent run takes a moment longer - the node's being careful, and that's the entire point.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| samples | LATENT | — | |
| vae | VAE | — | |
| force_fp32 | BOOLEAN | true | Force fp32 during VAE decode for maximum quality. |
| tile_size | INT | 00–1024 | Spatial tile size (0=auto/no tiling). Set 256+ for 1080p. |
| apply_aces | BOOLEAN | false | Apply ACES filmic tone mapping after decode. |
| exposure | FLOAT | 1.000.01–10 | Exposure for ACES (only used if apply_aces=True). |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |