LatentPhaseMagnitude
Blend two latents by structure and by texture, separately
- latent_0_batch
- latent_1_batch
- phase_mix_powers
- magnitude_mix_powers
- phase_luminositys
- phase_cyan_reds
- phase_lime_purples
- phase_pattern_structures
- magnitude_luminositys
- magnitude_cyan_reds
- magnitude_lime_purples
- magnitude_pattern_structures
- latent
Split any signal into a frequency decomposition and you get two independent things back: magnitude (how much energy is at each frequency - roughly, texture and contrast) and phase (where that energy sits - roughly, structure and shape). It's a classic signal-processing trick, and the classic demo of it is swapping the phase of one image onto the magnitude of another: the result reads structurally like the phase donor, even though none of its texture survived. LatentPhaseMagnitude applies that idea to a pair of ComfyUI latents, letting you dial in per-channel how much of each latent's phase and magnitude survives into the output.
RES4LYF's README describes a style-transfer feature built around exactly this kind of decomposition - pulling structure from one source and character from another. This node, and its three siblings (LatentPhaseMagnitudeMultiply, LatentPhaseMagnitudeOffset, LatentPhaseMagnitudePower), are the low-level tooling that makes that possible. This one is the "combine two latents" member of the family; the other three each operate on a single latent instead.
How it works
Both latent_0_batch and latent_1_batch get decomposed into phase and magnitude, per channel - luminosity, cyan-red, lime-purple, and pattern-structure, the four channels of a standard SD/SDXL-style latent. A dozen-plus float parameters (phase_luminosity, magnitude_cyan_red, and so on) then control how much of each channel's phase and magnitude come from latent 0 versus latent 1, with phase_mix_power and magnitude_mix_power as global exponents over the whole mix. Six boolean toggles (latent_0_normal, latent_1_normal, latent_out_normal, plus the matching _stdize and _meancenter sets) control normalization on the way in and out - worth leaving at their defaults (all true) until you have a specific reason to touch them.
The inputs and outputs that matter
latent_0_batch/latent_1_batch- the two latents you're blending.- The per-channel
phase_*andmagnitude_*floats - these are the actual mix controls, one pair per channel. Push a channel's phase toward one source and its magnitude toward the other to genuinely separate structure from texture. phase_mix_power/magnitude_mix_power- global exponents over the mix; leave at 1 for a linear blend.- Optional per-channel
SIGMASvariants (phase_luminositys,magnitude_cyan_reds, etc.) - schedule any of the above across steps instead of a fixed value. - Output:
latent- a single blended latent.
How to install it
Through ComfyUI Manager: search "RES4LYF" and install. Or manually, from ComfyUI/custom_nodes:
git clone https://github.com/ClownsharkBatwing/RES4LYF/
cd RES4LYF
pip install -r requirements.txt
Activate your venv first if you use one; on portable builds, use python_embedded\Scripts\pip.exe in place of pip. Restart ComfyUI afterward.
Common issues & troubleshooting
Results look muddy instead of like a clean blend. Leave the normalize/stdize/meancenter booleans at their defaults first - this pack ships them true for a reason, and turning them off before you understand the baseline behavior makes it much harder to tell what your phase/magnitude values are actually doing.
Nothing seems to change. This is a genuinely deep, undocumented corner of the pack - there's no written guide to what "good" per-channel values look like beyond the parameter names. Start by pushing one channel's mix hard toward 0 or hard toward 1 (rather than nudging fractionally) so you can actually see which channel controls what before fine-tuning.
You only have one latent, not two. If you're trying to reshape a single latent's own phase/magnitude rather than blend two together, this isn't the node - use LatentPhaseMagnitudeMultiply, LatentPhaseMagnitudeOffset, or LatentPhaseMagnitudePower instead, all of which take a single latent_0_batch.
Inputs (31)
| Name | Type | Default | Description |
|---|---|---|---|
| latent_0_batch | LATENT | — | |
| latent_1_batch | LATENT | — | |
| phase_mix_power | FLOAT | 1.000-10000–10000 | — |
| magnitude_mix_power | FLOAT | 1.000-10000–10000 | — |
| phase_luminosity | FLOAT | 0.000-10000–10000 | — |
| phase_cyan_red | FLOAT | 0.000-10000–10000 | — |
| phase_lime_purple | FLOAT | 0.000-10000–10000 | — |
| phase_pattern_structure | FLOAT | 0.000-10000–10000 | — |
| magnitude_luminosity | FLOAT | 0.000-10000–10000 | — |
| magnitude_cyan_red | FLOAT | 0.000-10000–10000 | — |
| magnitude_lime_purple | FLOAT | 0.000-10000–10000 | — |
| magnitude_pattern_structure | FLOAT | 0.000-10000–10000 | — |
| latent_0_normal | BOOLEAN | true | — |
| latent_1_normal | BOOLEAN | true | — |
| latent_out_normal | BOOLEAN | true | — |
| latent_0_stdize | BOOLEAN | true | — |
| latent_1_stdize | BOOLEAN | true | — |
| latent_out_stdize | BOOLEAN | true | — |
| latent_0_meancenter | BOOLEAN | true | — |
| latent_1_meancenter | BOOLEAN | true | — |
| latent_out_meancenter | BOOLEAN | true | — |
| phase_mix_powersopt | SIGMAS | — | |
| magnitude_mix_powersopt | SIGMAS | — | |
| phase_luminositysopt | SIGMAS | — | |
| phase_cyan_redsopt | SIGMAS | — | |
| phase_lime_purplesopt | SIGMAS | — | |
| phase_pattern_structuresopt | SIGMAS | — | |
| magnitude_luminositysopt | SIGMAS | — | |
| magnitude_cyan_redsopt | SIGMAS | — | |
| magnitude_lime_purplesopt | SIGMAS | — | |
| magnitude_pattern_structuresopt | SIGMAS | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| latent | LATENT | — |