Nodes/ComfyTV/Particles
ComfyUI Node

Particles

Sparks, embers, smoke, and magic dust — a 2D particle system with a live preview

By jtydhr88·Created 4 months ago·Updated about 8 hours ago· 1,057
Particles
  • video
  • mask_video
  • mask_image
  • video
◄force_run_token0►
◄project_id►
◄parent_output_id0►
◄emitterpoint►
◄e_x00.50►
◄e_y00.85►
◄e_x10.50►
◄e_y10.85►
◄rate120►
◄lifetime2.00►
◄speed120►
◄direction-90►
◄spread30►
◄gravity60►
◄wind0►
◄turbulence60►
◄turb_scale120►
◄drag0.10►
◄attract_strength0►
◄attract_x0.50►
◄attract_y0.50►
◄attract_radius0.50►
◄swirl0►
◄collidenone►
◄floor_y0.90►
◄bounce0.50►
◄sub_modenone►
◄sub_count8►
◄sub_speed120►
◄sub_lifetime0.60►
◄sub_size_ratio0.50►
◄sub_color#FFF2B0►
◄size12.0►
◄size_end_ratio0.40►
◄opacity_start1.00►
◄opacity_end0.00►
◄size_curve►
◄opacity_curve►
◄color0#FFD27A►
◄color1#FF5A2A►
◄spriteglow►
◄renderersprite►
◄stretch1.00►
◄trail_len4►
◄blendadditive►
◄warmup1.00►
◄seed7►

Particles is the node that makes your footage feel alive - sparks flying off a welder, embers drifting up from a fire, dust motes in a shaft of light, magic sparkle over a product. It's a full 2D particle simulator that composites onto your clip, and it has a live Canvas2D preview, which is the single most important feature it has: you dial the look before committing a render, instead of iterating blind on a GPU pass.

The schema is the biggest of anything in this pack - forty-odd parameters - but it's one simulation with sensible defaults, so don't panic. Here's how to read it.

The structure of a particle system

Emission - where particles are born. emitter (point default, or area), with e_x0/e_y0/e_x1/e_y1 defining the spawn region in normalized coordinates. rate is how many per second (default 120), lifetime how long each lives (2s). Drive emission from a mask and the emitter switches to mask_edge, spawning along the mask's outline - great for outlining a subject or the "dissolving into particles" effect.

Motion - the forces that push them around: speed, direction, spread (the cone), gravity, wind, turbulence + turb_scale (the organic wobble), drag, an attract_* group (a point they're pulled toward, with a radius), and swirl. There's also a collide option (with floor_y and bounce) if you want them to land on something.

Bursts - sub_mode/sub_count/sub_speed/sub_lifetime/sub_size_ratio/sub_color spawn secondary particles from each particle's death. This is how you get the "spark flies, then shatters" double-act.

Look - size and size_end_ratio (shrink over life), opacity_start/opacity_end, optional JSON size_curve/opacity_curve for per-life shaping, color0/color1 (gradient between them), sprite (e.g. glow), renderer (sprite, stretched streaks, or trail with trail_len), stretch, blend (additive default - that's the glow look), and warmup (seconds of sim to pre-run so the field is full on frame one). And seed, naturally.

The inputs and outputs

Optional inputs: video (the clip to composite onto - leave empty to render over a blank field), mask_video and mask_image (drive mask-edge emission). One output: video (COMFYTV_VIDEO).

A sane first pass: point emitter at the bottom of frame, rate ~120, lifetime ~2, speed ~120, direction -90 (up), spread ~30, a little turbulence, additive blend with the glow sprite. That's a firework or a campfire, depending on color. Tweak gravity and swirl to taste.

Install

Pack-wide one-liner:

cd ComfyUI/custom_nodes
git clone https://github.com/jtydhr88/ComfyTV

Restart ComfyUI - Desktop/macOS users: clone into the running instance by absolute path, verify __init__.py at the top level, and restart the backend, not just the browser. ComfyUI Manager finds it as "ComfyTV". No extra Python dependencies.

The trap here isn't install, it's over-parameterizing. Resist the urge to set all forty knobs - start with emission + one force + the look, preview live, and only add complexity when the shot demands it. And remember the output is a snapshot: re-run after changes, and Bridge out if you need native ComfyUI video downstream.

CategoryComfyTV/VideoFX

Inputs (50)

NameTypeDefaultDescription
force_run_tokenINT00–2147483647Internal — bumped on Run to invalidate ComfyUI's input cache.
project_idSTRINGInternal — populated by the projectStore on the frontend.
parent_output_idINT00–2147483647Internal — lineage parent set by spawn handlers on the frontend.
emitterCOMBOpoint5 options: point, line, rect, circle, mask_edge
e_x0FLOAT0.500–1—
e_y0FLOAT0.850–1—
e_x1FLOAT0.500–1—
e_y1FLOAT0.850–1—
rateFLOAT1200–2000—
lifetimeFLOAT2.000.1–10—
speedFLOAT1200–1200—
directionFLOAT-90-180–180—
spreadFLOAT300–180—
gravityFLOAT60-600–600—
windFLOAT0-600–600—
turbulenceFLOAT600–600—
turb_scaleFLOAT1208–600—
dragFLOAT0.100–0.99—
attract_strengthFLOAT0-600–600—
attract_xFLOAT0.500–1—
attract_yFLOAT0.500–1—
attract_radiusFLOAT0.500.05–1.5—
swirlFLOAT0-600–600—
collideCOMBOnone3 options: none, bounce, die
floor_yFLOAT0.900–1—
bounceFLOAT0.500–1—
sub_modeCOMBOnone3 options: none, on_death, on_collide
sub_countINT80–30—
sub_speedFLOAT1200–600—
sub_lifetimeFLOAT0.600.1–5—
sub_size_ratioFLOAT0.500.1–2—
sub_colorSTRING#FFF2B0—
sizeFLOAT12.01–64—
size_end_ratioFLOAT0.400–3—
opacity_startFLOAT1.000–1—
opacity_endFLOAT0.000–1—
size_curveSTRINGJSON [{t,v}] size multiplier over life
opacity_curveSTRINGJSON [{t,v}] opacity over life
color0STRING#FFD27A—
color1STRING#FF5A2A—
spriteCOMBOglow3 options: glow, spark, star
rendererCOMBOsprite3 options: sprite, stretched, trail
stretchFLOAT1.000–3—
trail_lenINT42–5—
blendCOMBOadditive2 options: additive, over
warmupFLOAT1.000–10—
seedINT70–99999—
videooptCOMFYTV_VIDEO—
mask_videooptCOMFYTV_VIDEO—
mask_imageoptCOMFYTV_IMAGE—

Outputs (1)

NameTypeDescription
videoCOMFYTV_VIDEO—