Nodes/radiance/Bit-Depth Degrade
ComfyUI Node

Bit-Depth Degrade

See the banding before your client does

By FXTD-Studios·Created 8 months ago·Updated about 18 hours ago· 246
Bit-Depth Degrade
  • image
  • quantized
  • delta_amplified
  • banding_mask
  • metrics
◄bit_depth8►
◄dither_modetriangular►
◄delta_gain10.0►
◄banding_threshold0.0040►
◄restore_from_quantizedfalse►

What it is

A quantiser. It rounds your image down to a lower bit depth, optionally dithers, and then shows you the damage: the quantised image, the error amplified, a mask marking where the error is worst, and a metrics string.

Why you'd want that: because you're delivering 8-bit and grading in 16-bit, and the first time you notice the sky in your render has visible steps in it shouldn't be after upload. This node lets you preview the quantisation on the exact encoding you're going to deliver in. It's a QA tool for the last step of a pipeline, and it's the kind of thing nobody builds because it's not fun, which is exactly why the pack having it is notable.

How it quantises

The input is treated as a display-encoded 0–1 image and quantised as is - no transfer conversion, no gamma handling. Values outside 0–1 are clipped. Alpha passes through untouched. So the rule is: feed it the image the way it will be delivered. If your delivery is sRGB-encoded 8-bit, hand it sRGB-encoded 0–1 data. If you feed it scene-linear, you're previewing the banding of a file you aren't making.

bit_depth (4 to 16, default 8) splits the 0–1 range into 2^bits − 1 steps. Straight quantisation, nothing clever.

dither_mode is the interesting control:

  • none is plain rounding - the worst case, and the honest baseline.
  • triangular (the default) adds random TPDF noise of ±1 step before rounding. This is what you want; dithering trades a little noise for the disappearance of banding contours, and triangular is the standard shape because it decorrelates the error from the signal.
  • floyd-steinberg is error diffusion - the classic scan-line look, computed a diagonal at a time. Push the error into neighbouring pixels instead of randomising. Sharper than TPDF, and it can produce visible texture patterns on flat areas.

Inputs and outputs

Beyond bit_depth and dither_mode, there are three optional controls. delta_gain (default 10) multiplies the absolute error for the delta_amplified output, clipped to 1 - that's the "look at how bad it is" view. banding_threshold (default 0.004, about one 8-bit code value) sets how much per-pixel error marks a pixel white in banding_mask. Note the tooltip's honesty there: it flags quantisation error, not detected bands. There's a difference and the node isn't pretending otherwise.

restore_from_quantized exists and currently does nothing - the node ignores it. The pack labels its own dead settings, which is better than the alternative, but you should know not to spend time on it.

Four outputs. quantized is the delivered image. delta_amplified is the amplified error, which is the one you look at - real banding shows up as visible contours there long before you can see it in the image. banding_mask is the same information as a binary mask, which means you can wire it into an inpainting or grain pass to fix only the affected regions. metrics is the string summary.

The practical move

Quantise, look at delta_amplified, and if there are contours, add grain or dither at delivery. This is the cheap, immediately useful version of a whole class of delivery bugs, and it's a lot faster than exporting a JPEG, uploading it, and squinting.

It's also the honest counterweight to a habit this ecosystem has: generating at 32-bit float precision and then piping the whole thing out as an 8-bit JPEG at quality 90. The last step is where your highlights die.

Install

ComfyUI Manager → search Radiance → install → restart → refresh the browser. Manually:

cd ComfyUI/custom_nodes
git clone https://github.com/fxtd-studios/radiance.git
cd radiance
python -m pip install -r requirements.txt

Windows portable users need the bundled python_embeded\python.exe for pip. No models involved. The pack's file-side dependencies (tifffile for 16/32-bit TIFF, OpenImageIO for DPX and EXR, OpenEXR for EXR on Python below 3.14) matter when you actually write the delivery, not for this preview.

Gotchas

  • Feeding scene-linear. You'll preview banding that doesn't apply to the file you're making. Match the encoding to the delivery.
  • Reading banding_mask as "bands detected". It's quantisation error above a threshold, per the tooltip. Correlation, not detection.
  • Toppling delta_gain and thinking the image is broken. It's an amplified error view; the default of 10 is chosen to be visible, not realistic.
  • Turning off dithering to avoid noise. You traded one artefact for a worse one. Banding is more objectionable than ±1 LSB of noise, which is why every delivery format worth its salt dithers.
  • Touching restore_from_quantized. It has no effect in this version.
CategoryFXTD STUDIOS/Radiance/VFX

Inputs (6)

NameTypeDefaultDescription
imageIMAGEDisplay-encoded 0..1 image, quantised as is (no transfer conversion); values outside 0..1 are clipped. Alpha passes through unchanged.
bit_depthINT84–16Target bits per channel; the 0..1 range is split into 2^bits - 1 steps.
dither_modeCOMBOtriangularnone: plain rounding. triangular: random TPDF noise of +/-1 step before rounding. floyd-steinberg: error diffusion (the classic scan-line result, computed a diagonal at a time).
delta_gainoptFLOAT10.01–100Multiplier on the absolute error |original - quantised| for the delta_amplified output, clipped to 1.
banding_thresholdoptFLOAT0.00400.0005–0.05Per-pixel error (0..1 units, largest channel) above which banding_mask is white. 0.004 is about one 8-bit code value. This flags quantisation error, not detected bands.
restore_from_quantizedoptBOOLEANfalseCurrently has no effect: the node ignores this setting.

Outputs (4)

NameTypeDescription
quantizedIMAGE—
delta_amplifiedIMAGE—
banding_maskIMAGE—
metricsSTRING—