Art FX
Turn footage into cartoon, charcoal, emboss, or halftone — no model, no prompt, no waiting
- video
- video
Most "make it look like a drawing" workflows in ComfyUI lean on a diffusion model - an img2img pass with a style prompt, a controlnet, a couple of minutes of GPU time. Art FX is the other way: a set of deterministic, per-frame filters that convert video to cartoon, charcoal, emboss, or halftone in seconds, with no model loaded and no prompt involved. It's the ComfyTV answer to the classic "posterize with extra steps" question, and it's genuinely useful when you want a stylized look that's stable - every frame gets the same treatment, so nothing flickers like a model-based stylization sometimes does.
Reach for it when you want a consistent illustrated look across a whole clip, or when you're producing a still-to-video sequence and want the whole thing to read as one art style. It's also a great thumbnail generator: emboss or halftone a frame and you've got instant graphic-design energy.
How it works
The mode combo picks the effect and the rest of the inputs are that effect's knobs. From the source, the four modes are:
- cartoon -
threshold(edge sensitivity, default 0.12),levels(color quantization, default 8), anddiff_space(edge detection spacing). This is the classic posterized-cartoon look: smooth flat colors with dark outlines. - charcoal -
edge_scale(default 1.5),scatter(how noisy the strokes get),color_mix(0–1, blend the original color back in),invert(white-on-dark vs dark-on-white). Best on high-contrast footage. - emboss -
azimuth(default 135°),elevation(default 30°),emboss_width(default 10). The lighting direction controls whether the relief reads as raised or carved. - halftone -
dot_radius(default 4) and the three screen anglesangle_c,angle_m,angle_y(cyan/magenta/yellow, defaults 15/45/0°). Classic comic-book dot screening per color channel.
The implementation is pure numpy - each frame gets a small custom DSP pass (per the pack's stylize_fx.py), no GPU needed, which is why it's fast and deterministic. The optional video input takes a COMFYTV_VIDEO and the single output is the stylized video. The internal force_run_token/project_id/parent_output_id inputs are ComfyTV frontend plumbing - leave them.
Installing ComfyTV
cd ComfyUI/custom_nodes
git clone https://github.com/jtydhr88/ComfyTV
Full backend restart, then it's under ComfyTV → VideoFX; ComfyUI Manager finds "ComfyTV". Zero extra Python deps (numpy does the work, and ComfyUI already ships it), no model files, nothing to download.
The usual install gotcha: on macOS / ComfyUI Desktop / multi-install setups, the relative cd can clone into the wrong instance - clone succeeds, nodes never appear. Get the running instance's path from the startup log, clone by absolute path into that instance's custom_nodes (quote paths with spaces/parentheses), confirm ComfyTV/__init__.py is top-level, restart the backend.
Common issues
- Cartoon looks noisy or mushy. Raise
thresholda bit and lowerlevels. If edges are too chunky, reducediff_space. - Charcoal is pure black mess.
color_mixdefaults to 0 (no original color). Bump it to ~0.3 for a softer, more readable look, and make sure the source is high contrast. - Emboss reads flat.
elevationis the culprit - low elevation flattens the relief. Also try rotatingazimuthso light comes from the top-left. - Halftone moiré. The three screen angles are per color channel; keep them far apart (15/45/0 is the default for a reason).
- The effect ignores my settings. Only the params for the active mode apply; cartoon doesn't read
dot_radius, halftone doesn't readthreshold. That's by design.
It's not going to beat a controlnet for "match this specific artist's style," but for fast, flicker-free, no-model illustration looks it's hard to beat. And it's free.
Inputs (19)
| Name | Type | Default | Description |
|---|---|---|---|
| force_run_token | INT | 00–2147483647 | Internal — bumped on Run to invalidate ComfyUI's input cache. |
| project_id | STRING | Internal — populated by the projectStore on the frontend. | |
| parent_output_id | INT | 00–2147483647 | Internal — lineage parent set by spawn handlers on the frontend. |
| mode | COMBO | cartoon | 4 options: cartoon, charcoal, emboss, halftone |
| threshold | FLOAT | 0.1200.01–1 | — |
| levels | INT | 82–32 | — |
| diff_space | INT | 11–4 | — |
| edge_scale | FLOAT | 1.500.1–8 | — |
| scatter | INT | 11–4 | — |
| color_mix | FLOAT | 0.000–1 | — |
| invert | BOOLEAN | false | — |
| azimuth | FLOAT | 1350–360 | — |
| elevation | FLOAT | 300–90 | — |
| emboss_width | FLOAT | 10.01–40 | — |
| dot_radius | FLOAT | 4.01–10 | — |
| angle_c | FLOAT | 150–360 | — |
| angle_m | FLOAT | 450–360 | — |
| angle_y | FLOAT | 00–360 | — |
| videoopt | COMFYTV_VIDEO | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| video | COMFYTV_VIDEO | — |