StructuredNoise
Give Your Sampler a Skeleton Before It Draws
- latent
- input_noise
- NOISE
"Structured noise" sounds like a contradiction - noise is supposed to be random, and structure is what noise destroys. This node makes both true at once. It hands your sampler a starting noise that looks statistically random at the pixel level but already carries the skeleton of an image you choose. It comes straight out of NeuralRemaster, a Toyota Research Institute paper from December 2025 ("Phase-Preserving Diffusion for Structure-Aligned Generation"), and right now it has basically zero community footprint - comfy.icu shows no impressions, so you'd be an early adopter. The payoff is a genuinely clever idea you won't find anywhere else on the registry.
Why you'd reach for it: the img2img trade. Normal img2img at high denoise re-rolls the layout and your composition drifts. At low denoise you keep the composition but barely change anything. That's the classic trade-off. StructuredNoise attacks the drift from the noise side: instead of starting from Gaussian static and hoping the prompt rebuilds the arrangement, it starts from noise whose low-frequency phase - the Fourier component that encodes edges, shapes, and global layout - was copied from your reference. The sampler then has no choice but to reconstruct that structure first, and only the high-frequency detail is free for your prompt to invent. Structure preservation with the same denoise range as img2img, but on a much stronger leash.
How it works (straight from the source). The node FFTs your reference latent and pulls out its phase and magnitude. It generates fresh Gaussian noise and does the same for it. Then a soft low-pass mask - a Gaussian falloff over transition_width - decides per frequency which phase wins: inside cutoff_radius you keep the image's phase, outside you keep the noise's phase. The magnitude stays noise-like (Rayleigh distributed, so the tensor still behaves like noise to the sampler), then everything goes back through an inverse FFT. The structure hides in the phase, which is exactly why it survives denoising into a coherent image. Reflection padding (pad_factor, default 1.5) suppresses the boundary ringing FFTs love to produce on small latents, and a final clamp swaps in raw noise wherever values blew past ±5.
The inputs that actually matter - the rest you can leave alone:
latent- your reference. To borrow structure from an existing image, VAEEncode it and feed that latent in. This defines the skeleton.cutoff_radius(default 40; tooltip: "Frequency cutoff radius (0 = full structure preservation)") - the single most important knob. Lower copies less of the image's structure; 0 means all of it.sampling_method(fft/cdf/two-gaussian) - three ways to get the same Rayleigh magnitude.fftis the default and fine.seed- fair warning from the code: the seed isn't actually wired into the noise math. Structured noise is deterministic given the reference latent, so reseeding won't vary your output. Change the latent or the cutoff instead.
There's also an optional input_noise latent if you want to feed your own noise tensor in rather than fresh Gaussian.
Output and wiring - this is where beginners trip. The output is a NOISE object, so it does not go into a normal KSampler's seed box. It plugs into the noise input on a custom-sampling node like SamplerCustom or SamplerCustomAdvanced. The noise object lazily resizes itself to whatever latent the sampler asks for, so it plays fine in multi-step advanced setups.
Install. Clone into custom_nodes and restart, or ComfyUI Manager → search "structured-noise" (pack title: Phase-Preserving Noise). No model files to download - it's pure torch. The repo's CLI path pulls in scikit-image, Pillow, and tqdm via setup.py, but the ComfyUI node itself only really needs torch.
Gotchas. It targets the new ComfyUI extension API (comfy_api.latest, ComfyExtension) - if the node doesn't appear after a restart, your ComfyUI is too old; update it first. First renders can look like "nothing happened" because the output is still noise; compare against a plain txt2img at the same settings to see the composition lock. And check the license before commercial work: setup.py declares CC-BY-NC-4.0, which is non-commercial.
Inputs (8)
| Name | Type | Default | Description |
|---|---|---|---|
| latent | LATENT | — | |
| seed | INT | 00–18446744073709550000 | — |
| noise_std | FLOAT | 1.00–10 | — |
| cutoff_radius | FLOAT | 400–1000 | Frequency cutoff radius (0 = full structure preservation) |
| transition_width | FLOAT | 2.00.1–20 | — |
| pad_factor | FLOAT | 1.51–3 | — |
| sampling_method | COMBO | fft | 3 options: fft, cdf, two-gaussian |
| input_noiseopt | LATENT | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| NOISE | NOISE | — |