Latent math
Blend latents with an expression — cheap, because it never touches pixels
- a
- b
- c
- d
- LATENT
Latent math applies an expression to the compressed representation of your images - the latent tensor the diffusion model actually works in - rather than to pixels. The default expression, a*(1-w)+b*w, is a weighted blend of two latents, which is the same operation as the core "Latent Blend" node but written as math you control. Because latents are roughly an eighth the size of the images they decode to, this runs fast even when your graph is doing something fiddly per frame.
How it works
A LATENT in ComfyUI is a dict holding a samples tensor, and that tensor is what this node evaluates your expression on. Inside the expression you get the standard kit: a, b, c, d for the input latents (missing ones default to zero), w, x, y, z as floats, plus positional variables - B/T/N (batch, batch count, channel count), X/Y, W/H (note: these are latent-space dimensions, not pixel dimensions), and per-dimension index tensors. So you can blend per-position, per-channel, or just uniformly.
The length_mismatch combo handles different batch sizes: tile repeats, error (the default) throws, pad zero-fills.
The inputs that matter
a- required latent.b,c,doptional.Latent- the expression. Defaulta*(1-w)+b*w.length_mismatch-tile/error/pad.w,x,y,z- float knobs for your expression.
Output is a LATENT, ready to feed a sampler or a VAE decode.
Installing it
It's part of More Math (mcDandy/more_math). ComfyUI Manager - search "More Math" - or:
cd ComfyUI/custom_nodes
git clone https://github.com/mcDandy/more_math
cd more_math
pip install -r requirements.txt
Restart. Dependencies are just antlr4-python3-runtime and torch, no downloads. Pack-wide gotcha: it needs a current ComfyUI (newer node API), so update ComfyUI if the nodes don't show.
Where people get burned
The trap is expecting latent numbers to behave like pixel numbers. Latents live in a compressed, roughly zero-centered distribution - a "0.5" in latent space is not mid-gray, and a+b on two latents is not additive lighting the way it is on images. If you want intuitive 0–1 semantics, do the math on pixels (Image math) and encode; do it on latents when you specifically want to manipulate the thing the sampler sees, like latent interpolation between two images for video morphing, or pre-sampling manipulation.
Second, mixing latents from different VAE families (or wildly different scales) gives you mud. Keep the inputs coming from the same model's VAE. Third, length_mismatch defaults to error - a one-image latent against a batch will throw until you set tile or pad.
And the standing pack note: the classic form here is deprecated in favor of an autogrow "Latent math" variant that takes more inputs. Both ship and work; the newer one is the better pick for a fresh workflow.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| a | LATENT | — | |
| Latent | STRING | a*(1-w)+b*w | Expression to apply on input latents |
| length_mismatch | COMBO | error | How to handle mismatched latent batch sizes. tile: repeat shorter inputs; error: raise error on mismatch; pad: treat missing frames as zero. |
| bopt | LATENT | — | |
| copt | LATENT | — | |
| dopt | LATENT | — | |
| wopt | FLOAT | 0.00 | — |
| xopt | FLOAT | 0.00 | — |
| yopt | FLOAT | 0.00 | — |
| zopt | FLOAT | 0.00 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| LATENT | LATENT | — |