Donut Spectral Sharpener
Spectral sharpening with a reference
- input_image
- reference_image
- enhanced_image
- noise_reference
- enhancement_report
- spectral_analysis
AI images have a tell: the surface is too clean. Real photographs carry noise structure - grain, micro-contrast, texture at every frequency - and diffusion models usually don't. Donut Spectral Sharpener attacks that specific gap. It's a frequency-domain enhancer that can match your image's spectral texture to a real photo's, synthesize believable grain, or just amplify what's already there. That's a much more interesting tool than a sharpening kernel, because the goal isn't "more edge contrast" - it's "convince the eye this was shot, not rendered."
This is the pack's current sharpener, the one that absorbed the two deprecated "Donut Sharpener" nodes. If you meet either of those in an old workflow, replace it with this.
How it works
The engine decomposes the image into frequency bands and works in the Fourier domain, separating amplitude from phase so it can boost detail without blowing out brightness. When a reference is involved, it matches the input's band structure toward the reference's spectral character. Recombination uses a darken blend with the original, which is the anti-halo mechanism - the thing that keeps "enhanced" from turning into "crunchy edges."
The one input that defines the whole behavior is reference_source:
external_reference- match the spectrum of the image you plug into reference_image. This is the flagship mode: grab a photo with the film look you want, and the node transfers its texture. If you leave the reference unwired it falls back to the input image, so it won't hard-fail.generated_noise- synthesize a reference from one of six noise types (gaussian,perlin,film_grain,sensor_noise,uniform,realistic_grain). Good when you want a specific film-grain aesthetic without hunting for a photo.self_amplify- boost the image's own high frequencies with no reference at all. Honest answer: that's an unsharp mask with a fancier coat of paint.
The rest of the knobs, in rough order of importance:
- enhancement_strength - how far to push the effect (0–1000, default 1).
- blend_factor - how much result vs. original (default 0.8). Lower it when edges start to halo.
- spectral_mode -
full_spectrum,high_freq_only, oradaptive. For subtlety,high_freq_only. - frequency_bands - 8–32 (default 16). More bands = more surgical, slower.
- noise_strength / noise_scale / noise_saturation - tune the synthesized grain in
generated_noisemode.
Four outputs: enhanced_image, noise_reference (the reference used - your photo, or the synthesized grain), plus enhancement_report and spectral_analysis strings if you want diagnostics.
Where it fits
Use it as a post-process on hero shots, after VAE decode, before final save - especially on SDXL work where "plastic skin" is a recurring complaint. Pair it with a face detailer if you're upscaling, since every enhancement pass slightly rewrites texture. The honest caveat: for adding detail to a small or soft image, generative upscalers (SeedVR2 and friends) are the more powerful mainstream answer. This node's niche is matching a reference's texture - nothing else in the pack does that.
Install
Part of ComfyUI-DonutNodes: ComfyUI Manager → search "DonutNodes" → install → restart. Manual:
cd ComfyUI/custom_nodes
git clone https://github.com/DonutsDelivery/ComfyUI-DonutNodes.git donutnodes
cd donutnodes
python -m pip install -r requirements.txt
Heavy dependencies? No - opencv-python-headless, scipy, matplotlib, psutil, tqdm, requests, no model files. It's a pure image-op, so it runs on CPU if it has to, though it'll be snappier with a GPU available.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| input_image | IMAGE | — | |
| reference_source | COMBO | external_reference | 3 options: external_reference, generated_noise, self_amplify |
| reference_imageopt | IMAGE | — | |
| enhancement_strengthopt | FLOAT | 1.00–1000 | — |
| frequency_bandsopt | INT | 168–32 | — |
| noise_typeopt | COMBO | gaussian | 6 options: gaussian, perlin, film_grain, sensor_noise, uniform, realistic_grain |
| noise_strengthopt | FLOAT | 00–100 | — |
| noise_scaleopt | FLOAT | 1.00.1–10 | — |
| noise_saturationopt | FLOAT | 1.000–1 | — |
| spectral_modeopt | COMBO | full_spectrum | 3 options: full_spectrum, high_freq_only, adaptive |
| blend_factoropt | FLOAT | 0.80–1 | — |
Outputs (4)
| Name | Type | Description |
|---|---|---|
| enhanced_image | IMAGE | — |
| noise_reference | IMAGE | — |
| enhancement_report | STRING | — |
| spectral_analysis | STRING | — |