Nodes/Skoogeer-Noise/Fluid Image Advection
ComfyUI Node

Fluid Image Advection

Melt Your Image Into Paint With a Real Fluid Simulation

By ttulttul·Created 8 months ago·Updated 2 months ago· 14
Fluid Image Advection
  • image
  • mask
  • image
  • velocity_preview
steps20
dt1.00
resolution_scale0.50
force_count3
force_strength5.0
force_radius0.10
swirl_strength2.0
velocity_damping0.980
diffusion0.00
vorticity0.00
seed0
wrap_modeclamp

Fluid Image Advection distorts an image by literally pushing its pixels through a simulated fluid. Not a blur, not a warp filter with a clever name - a real velocity field, evolving over time, carrying color with it. Feed it a portrait and you get oil-paint swirling. Feed it a landscape and you get a marbled, ink-in-water mess you'd never get from a fixed warp. It's from the same stable-fluids family as the pack's smoke nodes, minus the buoyancy: pure viscous flow, stirred by random forces.

The algorithm is worth knowing because it explains every slider on the node. Each step: a few random forces ("sticks") jab the velocity field, the field optionally diffuses and gets vorticity confinement applied (so the motion curls instead of going straight), velocity advects itself, damping bleeds energy out, and finally the image color field is advected through the resulting velocity. Repeat for steps. Semi-Lagrangian advection is what keeps the whole thing stable at the big time steps these nodes use.

The inputs that actually matter:

  • steps and dt - how long and how big the time steps are. More steps, more smear.
  • resolution_scale - the sim runs internally at this fraction of image resolution. Lower = faster and chunkier. This is your speed dial.
  • force_count, force_strength, force_radius - how many sticks jab per step, how hard, and how wide. More or harder forces = more violent deformation.
  • swirl_strength - a rotational component added around each stick, which is what makes the flow curl.
  • velocity_damping - lower values settle the flow faster (more viscous look). 0.98 default means it keeps sloshing.
  • vorticity - curl enhancement on top. This is the "make it billow" control.
  • wrap_mode - how advection samples outside the image: clamp, wrap, or mirror. wrap gives that seamless infinite-texture look.

It returns the distorted image plus a velocity_preview image so you can see the flow field - genuinely useful for understanding why the deformation went somewhere weird. An optional mask input limits the distortion to masked areas, which is how you turn "whole image melting" into "this one region is melting."

Where it fits

Two classic uses: (1) as a stylization stage - run it on a render, then img2img at low denoise so the model re-interprets the smears as paint, smoke, or water instead of just noise; (2) as a motion source for animation - the velocity field is deterministic per seed, so you can re-run with different steps or interpolate force_strength to fake an evolving flow. There's also a Latent variant of this exact node if you want the deformation to happen pre-decode.

Installing

Part of the Skoogeer-Noise pack by ttulttul:

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

Restart, or install via ComfyUI Manager ("Skoogeer-Noise"). Deps are just torch/numpy/einops/pyyaml - no models, no downloads, pure math.

Gotchas

The number-one surprise is speed. This is a real simulation; a full-res image with steps in the hundreds will take a while, and it runs on CPU tensors. Drop resolution_scale to 0.5 and don't be shy about it. Second: zero force_count means a static image with extra steps - if nothing happens, check that forces are actually being injected. And if your edges go weird, that's wrap_mode doing its job; mirror is the flattering option for most images. Keep the folder named Skoogeer-Noise or the import breaks - the module path is custom_nodes.Skoogeer-Noise.

Categoryimage/perturb

Inputs (14)

NameTypeDefaultDescription
imageIMAGEImage to distort by fluid advection.
stepsINT200–256Number of simulation steps.
dtFLOAT1.000–4Time step size used during semi-Lagrangian advection.
resolution_scaleFLOAT0.500.25–1Internal simulation resolution scale (lower = faster).
force_countINT30–64Number of random force injections ('sticks') per step.
force_strengthFLOAT5.00–256Linear force magnitude added to velocity (in pixels / step).
force_radiusFLOAT0.100–1Normalized radius of influence (0.1 = 10% of min(width,height)).
swirl_strengthFLOAT2.00–256Rotational component added around each stick position.
velocity_dampingFLOAT0.9800–1Velocity decay applied each step (lower = more viscous / quickly settles).
diffusionFLOAT0.000–1Optional velocity diffusion (simple Gaussian smoothing).
vorticityFLOAT0.000–10Vorticity confinement strength (adds swirling detail).
seedINT00–18446744073709550000Seed controlling the random stick injections.
wrap_modeCOMBOclampHow advection samples outside the bounds.
maskoptMASKOptional mask to limit the effect to masked areas (mask is resized to image resolution).

Outputs (2)

NameTypeDescription
imageIMAGE
velocity_previewIMAGE