Nodes/RyanOnTheInside/Particle Emission Mask βš‘πŸ…‘πŸ…žπŸ…£πŸ…˜
ComfyUI Node

Particle Emission Mask βš‘πŸ…‘πŸ…žπŸ…£πŸ…˜

The node that actually runs the particle simulation

By ryanontheinsideΒ·Created 2 years agoΒ·Updated 5 months agoΒ· 852
Particle Emission Mask βš‘πŸ…‘πŸ…žπŸ…£πŸ…˜
  • masks
  • emitters
  • vortices
  • wells
  • static_bodies
  • MASK
  • IMAGE
β—„strength1.00β–Ί
β—„invertfalseβ–Ί
β—„subtract_original0.00β–Ί
β—„grow_with_blur0.0β–Ί
β—„particle_count200β–Ί
β—„particle_lifetime4.0β–Ί
β—„wind_strength0β–Ί
β—„wind_direction0β–Ί
β—„gravity0β–Ί
β—„warmup_period0β–Ί
β—„start_frame0β–Ί
β—„end_frame0β–Ί
β—„respect_mask_boundaryfalseβ–Ί
β—„emission_strength1.00β–Ί
β—„well_strength_multiplier1.0β–Ί

Every other particle node in this pack - ParticleEmitter, GravityWell, Vortex, the modulation nodes - produces a definition, not an effect. This is the one that actually runs the simulation. Feed it one or more emitters and, optionally, the force fields you want acting on them, and it steps the physics forward frame by frame on pymunk (a real physics engine, not an approximation) and renders the result as a mask and an image.

How it works

emitters takes a PARTICLE_EMITTER - usually a chain built from ParticleEmitter nodes stacked via previous_emitter. vortices and wells optionally add VORTEX and GRAVITY_WELL force fields into the mix, with well_strength_multiplier as a global dial on how hard the gravity wells pull without having to re-tune each one individually. static_bodies optionally adds fixed collision obstacles particles can bounce off.

Beyond the force fields, this node owns its own simulation-wide settings: particle_count (a hard cap, up to 10,000), particle_lifetime (in seconds, how long each particle survives before disappearing), wind_strength/wind_direction (a uniform force across the whole system, independent of any gravity well or vortex), gravity (straight-down pull, separate from the point-based GravityWell nodes), and warmup_period - frames simulated before the visible output starts, useful for letting a system settle into a natural-looking state instead of starting from a jarring empty frame.

masks and the shared strength/invert/subtract_original/grow_with_blur set are the same base contract used across this pack's mask nodes, applied on top of the simulation result. respect_mask_boundary is the standout option here - turned on, particles physically collide with the mask's edges rather than just being confined to spawning inside it, so a mask becomes an actual solid boundary in the simulation, not just a spawn region. emission_strength scales the whole effect's intensity, and start_frame/end_frame bound when emission is active.

The inputs and outputs that matter

  • emitters (required, PARTICLE_EMITTER) - from ParticleEmitter.
  • vortices / wells / static_bodies (optional) - force fields and obstacles.
  • particle_count (default 200), particle_lifetime (default 4s) - simulation scale.
  • gravity, wind_strength/wind_direction - global forces.
  • respect_mask_boundary - makes the mask a physical collision boundary.

Two outputs: MASK (the particle system rendered as a mask, ready for compositing) and IMAGE (a rendered preview of the same simulation).

How to install it

ComfyUI Manager: search "RyanOnTheInside", install, restart. Manually:

cd ComfyUI/custom_nodes
git clone https://github.com/ryanontheinside/ComfyUI_RyanOnTheInside
cd ComfyUI_RyanOnTheInside
pip install -r requirements.txt

then restart. This node depends on pymunk for physics and (per the rendering output) likely pygame, both pinned in requirements.txt - a pymunk version mismatch is a known way for this entire particle-system side of the pack to fail on install.

Common issues & troubleshooting

Built emitters and force fields but nothing shows up here. This is the single node that actually runs the simulation - check that your ParticleEmitter chain (and any GravityWell/Vortex nodes) are wired into this node's emitters/vortices/wells inputs specifically. It's easy to build the whole chain and forget the final connection.

Simulation is painfully slow on longer sequences. particle_count at the high end combined with a long frame range is genuinely expensive - this is a per-frame physics simulation and render, not a cheap filter. Drop particle_count or particle_lifetime before assuming something's misconfigured.

Particles pass straight through your mask despite respect_mask_boundary. Confirm it's actually toggled on (it defaults to off) - without it, the mask only constrains where particles spawn, not where they can travel afterward.

CategoryRyanOnTheInside/ParticleSystems

Inputs (20)

NameTypeDefaultDescription
masksMASKInput mask or sequence of masks to be processed (MASK type)
strengthFLOAT1.000–1Overall strength of the mask effect (0.0 to 1.0)
invertBOOLEANfalseWhen enabled, inverts the mask output (black becomes white and vice versa)
subtract_originalFLOAT0.000–1Amount of the original mask to subtract from the result (0.0 to 1.0)
grow_with_blurFLOAT0.00–10Amount of Gaussian blur to apply for mask growth (0.0 to 10.0)
emittersPARTICLE_EMITTERList of particle emitter configurations (PARTICLE_EMITTER type)
particle_countINT2001–10000Maximum number of particles in the system (1 to 10000)
particle_lifetimeFLOAT4.00.1–10How long each particle lives in seconds (0.1 to 10.0)
wind_strengthFLOAT0-100–100Strength of the wind force (-100.0 to 100.0)
wind_directionFLOAT00–360Direction of the wind in degrees (0.0 to 360.0)
gravityFLOAT0-1000–1000Strength and direction of gravity (-1000.0 to 1000.0)
warmup_periodINT00–1000Number of frames to simulate before starting (0 to 1000)
start_frameINT00–1000Frame to start particle emission (0 to 1000)
end_frameINT00–1000Frame to end particle emission (0 to 1000, 0 means until end)
respect_mask_boundaryBOOLEANfalseWhether particles should collide with mask boundaries
emission_strengthFLOAT1.000–1Strength of particle emission effect (0.0 to 1.0)
vorticesoptVORTEXOptional list of vortex configurations (VORTEX type)
wellsoptGRAVITY_WELLOptional list of gravity well configurations (GRAVITY_WELL type)
well_strength_multiplieroptFLOAT1.00–10Global multiplier for gravity well strengths (0.0 to 10.0)
static_bodiesoptSTATIC_BODYOptional list of static collision bodies (STATIC_BODY type)

Outputs (2)

NameTypeDescription
MASKMASKβ€”
IMAGEIMAGEβ€”