🌊 ComfyUIFlowFields
Flow-field art you can actually steer
- particle_image
- density_mask
- flow_map
This node makes the kind of image you'd normally fight a particle sim all afternoon for: swirling, ink-in-water trail lines, in under a second. One node, no model, no VRAM. It builds a flow field - a mathematical "wind map" across the canvas - drops particles in, and renders where they get blown. And the name is a lie in the best way: no API, no key, and its only link to AI is that it produces conditioning you can hand to the real model.
It's from ComfyUIFlowFields, a solo pack by javierjarart (Javier Jara), MIT-licensed and in the Comfy Registry. Small, fresh, README in Spanish, but well built - clean core//nodes/ split, a real pytest suite, and one bugfix you wouldn't expect from a weekend node (more below). It ships a single node, FlowFieldGenerator, under the Jarart Tools category.
How it works
The core is curl noise, a divergence-free vector field - think incompressible fluid, so nothing pools or vanishes; particles follow a coherent swirl instead of drifting into a dead spot. The field is a fractal sum of sinusoids (noise_octaves sets the fBm layers), and the flow direction comes from the gradient of that scalar noise.
Particles spawn, then advect step by step: each samples the field via bilinear interpolation, moves along it, and wraps at the canvas edges like a torus. Every step draws a short segment per particle onto a fading canvas - that's the trails - while a separate accumulator tracks raw density for the mask. The whole sim is numpy + Pillow on CPU; torch only appears at the end to convert arrays to tensors.
The inputs that actually matter
Fourteen inputs, and you'll touch maybe five. The rest are fine at defaults:
noise_scale- the big one. Lower = broader, smoother swirls; higher = tighter, busier turbulence. Default 0.008 is a good starting point for organic looks.steps- more steps = longer trails. Default 150 is plenty for a poster; the trails get denser and more tangled as you climb.fade- how fast trails persist before the background wipes them. Lower fades give thin current-like streaks; higher builds up thick glowing rivers.spawn_mode- where particles start:random,center,grid, orcircle.centerwith a lowfadegives a nice radial burst;gridis a uniform texture.flow_angle- rotates the entire field 0–360°, handy for a diagonal sweep.seed- reproducibility, natch.
color_mode (rainbow, fire, ocean, monochrome, custom) and bg_color_hex are cosmetic; width/height, particle_count, speed, and line_width do what they say.
The three outputs
particle_image- the RGB trails. Save it or preview it, or use it as an IP-Adapter style reference on an SD1.5/SDXL workflow (that adapter path mostly isn't there on modern Flux-era bases).density_mask- a soft MASK of everywhere particles passed. The sneaky-useful one: wire it into Set Latent Noise Mask before a KSampler and sampling focuses on the swirl regions, the mask-driven trick from the KB's detailing playbook. Preview it via MaskToImage.flow_map- a color-coded map of the field (R = X direction, G = Y direction, B = magnitude). It's a guide image, not a true ControlNet preprocessor output - treat it as a visual reference, not plug-and-go.
Installing it
Two ways, both painless:
# ComfyUI Manager: search "ComfyUIFlowFields" and install
# or, by hand:
cd ComfyUI/custom_nodes && git clone https://github.com/javierjarart/ComfyUIFlowFields
Restart and done. Dependencies are numpy, Pillow, and torch - all already in ComfyUI, so no model downloads, no heavy installs. That's the whole appeal: the anti-node of a 5GB checkpoint.
Gotchas worth knowing
bg_color_hexexpects exactly six hex digits, no#. Malformed values (like the#0A0A14you'll instinctively type) get rejected before the sim runs with a clear error, not a mid-render crash.- The seed trap is already fixed. ComfyUI's randomize button rolls 64-bit seeds; numpy's
RandomStateonly accepts 32-bit, a recipe for crashes. This pack masks seeds down to 32 bits, so any seed works - just know a seed and its value plus 2³² produce the same image. - It's a CPU sim, so respect the sliders. Each step draws one line per particle in a Python loop. Defaults (800 × 150) run in a couple of seconds; 5000 particles × 1000 steps is tea time. Keep
stepsmodest unless you're chasing long trails. - Particles wrap around the canvas edges (torus world). The renderer skips the wrap jump so you don't get a stray long streak - but particles do teleport to the far side, which shapes the composition in surprising ways.
If you want organic background texture, or a mask to steer a masked sampling pass, this is the one to reach for. It won't change your life, but it costs nothing to run and it's genuinely fun to dial in.
Inputs (14)
| Name | Type | Default | Description |
|---|---|---|---|
| width | INT | 51264–2048 | Ancho del canvas |
| height | INT | 51264–2048 | Alto del canvas |
| particle_count | INT | 80010–5000 | Cantidad de partículas |
| noise_scale | FLOAT | 0.0080.001–0.1 | Frecuencia base del noise (más bajo = flujos más amplios) |
| noise_octaves | INT | 41–8 | Octavas de fractal noise (fBm) |
| speed | FLOAT | 2.50.1–20 | Velocidad de las partículas |
| steps | INT | 15010–1000 | Pasos de simulación (más pasos = trails más largos) |
| fade | FLOAT | 0.920.5–0.999 | Factor de fade del trail (más bajo = se borra más rápido) |
| line_width | FLOAT | 1.00.5–4 | Grosor de línea de cada partícula |
| seed | INT | 420–4294967295 | Semilla para reproducibilidad |
| color_mode | COMBO | rainbow | Paleta de colores de las partículas |
| spawn_mode | COMBO | random | Distribución inicial de partículas |
| bg_color_hex | STRING | 0A0A14 | Color de fondo en hex (sin #) |
| flow_angle | FLOAT | 00–360 | Rotación del campo de flujo en grados |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| particle_image | IMAGE | — |
| density_mask | MASK | — |
| flow_map | IMAGE | — |