Nodes/ComfyTV/Regrain
ComfyUI Node

Regrain

Film Grain That Doesn't Look Like Noise (ComfyTV Regrain)

By jtydhr88·Created 3 months ago·Updated about 15 hours ago· 725
Regrain
  • video
  • video
force_run_token0
project_id
parent_output_id0
grain_size0.80
shadows0.30
midtones0.15
highlights0.05
grain_sat0.40
seed7

AI-generated video has one tell: it's too clean. Flat, waxy, zero texture - the kind of image that screams "rendered" the second it hits a timeline. Regrain is the ComfyTV answer: it adds analog-style film grain back, but with enough control that you can make it read as stock footage grain instead of YouTube compression noise.

It's one of the ~190 stages in ComfyTV (jtydhr88's canvas-based take on ComfyUI - every operation is its own node, results flow downstream as snapshots). The Regrain node sits under ComfyTV/VideoFX and does its work through the pack's shared FX engine, which means it previews live in the node and only bakes to a file when you run a final FX Chain pass. Same grain every frame, no flicker fights.

How it works

The thing that separates this from a dumb "add noise" node is that grain is split by luminance zone. You get three separate strength knobs - shadows, midtones, highlights (each 0–1) - so you can grain up the shadows where real film grain lives while leaving highlights mostly clean, instead of dousing the whole frame. grain_size (0–4, default 0.8) sets the physical size of the grain particles, and grain_sat (0–1, default 0.4) controls how much chroma the grain carries. A seed input (default 7) keeps the pattern stable across a shot so consecutive clips don't shimmer differently.

Under the hood it builds an FX spec and hands it to the torch-based FX runner - no external dependencies, no model downloads, just the numpy/torch stack ComfyUI already ships. That's a recurring ComfyTV trait worth knowing: the pack declares zero extra Python dependencies.

Inputs and outputs

The inputs you actually touch: grain_size, shadows, midtones, highlights, grain_sat, and seed. Everything else in the schema - force_run_token, project_id, parent_output_id - is internal plumbing the frontend fills in for project bookkeeping; ignore it. Feed an optional video in, get video back out, ready to wire into the next stage or a Keying/Compose node.

Getting it installed

ComfyTV installs like any pack: search "ComfyTV" in ComfyUI Manager, or

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

then restart ComfyUI. The nodes appear under the ComfyTV category. If you're on ComfyUI Desktop or macOS, the classic cd ComfyUI/custom_nodes can land in the wrong instance - read the startup log for the running base path and clone into that absolute path instead (watch for a nested ComfyTV/ComfyTV/ layout after cloning; the inner folder needs to move up one level). A full backend restart, not a browser refresh, is what registers the nodes.

Troubleshooting

  • Grain looks like static, not film. Almost always grain_size too small or shadows/highlights both cranked to 1. Start at defaults and raise one zone at a time.
  • Colors shift weirdly. grain_sat is the knob - drop it toward 0.2 for a monochrome-ish grain that won't tint your grade.
  • Nothing changes after Run. If all three zone sliders are at 0 the node short-circuits and passes the video through untouched (that's intentional - it's the identity case).
  • Grain shimmering across cuts. Match the seed between shots so the grain pattern is consistent.
CategoryComfyTV/VideoFX

Inputs (10)

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.
grain_sizeFLOAT0.800–4
shadowsFLOAT0.300–1
midtonesFLOAT0.150–1
highlightsFLOAT0.050–1
grain_satFLOAT0.400–1
seedINT70–99999
videooptCOMFYTV_VIDEO

Outputs (1)

NameTypeDescription
videoCOMFYTV_VIDEO