Nodes/ComfyTV/Particles
ComfyUI Node

Particles

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

By jtydhr88·Created 3 months ago·Updated about 16 hours ago· 725
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