Nodes/Skoogeer-Noise/Split Latent (FFT Mag/Phase)
ComfyUI Node

Split Latent (FFT Mag/Phase)

Take a latent apart in the frequency domain

By ttulttul·Created 9 months ago·Updated 3 months ago· 14
Split Latent (FFT Mag/Phase)
  • latent
  • MAGNITUDE
  • PHASE

Every latent you've ever decoded is secretly the sum of waves. Take the 2D Fourier transform of the samples and you get two components that describe those waves completely: the magnitude (how strong each frequency is) and the phase (how the waves align in space). This node does exactly that - torch.fft.fft2 over the spatial dims of your latent, split into one latent holding magnitude and one holding phase. Two LATENT outputs: MAGNITUDE and PHASE.

Why bother? Because the two halves carry completely different kinds of information, and editing them separately is a well-known trick in signal processing that maps surprisingly well onto image aesthetics. The magnitude spectrum encodes the overall frequency character - how much fine detail vs. broad structure exists. The phase encodes where things are - the actual layout, edges, and spatial arrangement. Clamp or smooth the magnitude and you change texture/softness while keeping composition. Shuffle or corrupt the phase and you scramble where everything is. If you've ever seen "phase scramble" artifacts that look like an image exploded into glass shards, that's phase being destroyed.

The inputs and output

One input: latent, a spatial latent. Two outputs: MAGNITUDE and PHASE, both LATENT with the same shape as the input - the pack stores them as regular latents, not complex tensors, so they flow through normal sockets. To get back to a spatial latent, you run them through the pack's combine sibling, which reconstructs via torch.polar + inverse FFT. In other words, the pattern is split → edit one half → combine.

A couple of implementation notes from the source worth knowing. The node runs under no_grad and picks the storage dtype so it doesn't blow up precision, falling back to float32 if the native dtype FFT fails. And because both outputs copy the input latent dict and just swap in their "samples", any extra keys (like a noise_mask) ride along - useful if you're splitting a masked latent.

Installing and using it

Part of Skoogeer-Noise. ComfyUI Manager → search "Skoogeer-Noise", or:

cd ComfyUI/custom_nodes
git clone https://github.com/ttulttul/Skoogeer-Noise

Restart ComfyUI. No models or keys; deps are torch, numpy, einops, pyyaml.

Where this actually earns its keep

Honestly, frequency-domain latent surgery is a niche, and the pack's other frequency tool (Latent Frequency Split - a Gaussian low/high split that's far more approachable) will cover most "soften the detail" use cases with one dial. This FFT node is for the experiments: cross-breeding two latents by mixing magnitudes, normalizing one latent's frequency character toward another, or building structured-frequency noise. One warning: these outputs are not "images in disguise" - the magnitude latent is dominated by a huge DC/low-frequency component, so don't expect it to look meaningful in a previewer. And don't edit one half without recombining - feeding a magnitude latent straight to a sampler is asking for nonsense. Split, edit, combine, then decode.

Categorylatent/frequency

Inputs (1)

NameTypeDefaultDescription
latentLATENTSpatial latent to transform into frequency magnitude + phase latents.

Outputs (2)

NameTypeDescription
MAGNITUDELATENT
PHASELATENT