Z Defocus
Real bokeh on AI video — if you feed it a depth map
- video
- depth_image
- depth_video
- video
Z Defocus is the ComfyTV stage that fakes a real lens: it takes your clip plus a depth map, and blurs by depth - so the background gets a genuine bokeh while the subject stays sharp. It's the difference between an AI video that looks generated and one that looks shot on a cinema lens. This is the one node of the four worth installing ComfyTV for on its own.
The catch, and it's a real one: it needs a depth map. Unlike the pack's other FX stages, which just need a video, Z Defocus will refuse to run without one. That depth map is exactly what depth-estimation models produce - Depth Anything is the usual source, and the KB's take on it holds here: it's a single-image estimator that's become the ecosystem default, so you almost certainly already have a workflow that can emit one.
How it works
Per frame, it reads the depth map and computes a per-pixel circle of confusion: pixels whose depth falls inside focus_range around focus_depth stay sharp; everything else gets a blur radius scaled up to max_radius. The depth range is sliced into layers bins, each bin is blurred with a bokeh-shaped kernel (a true disc or a hexagon), and the slices are composited front-to-back so foreground stays in front of background - the "painter's algorithm" trick that real DOF compositors use. highlight_boost multiplies bright pixels before the blur, which is what makes hot speculars bloom into those soft, expensive-looking bokeh circles. If your depth convention is inverted (near objects dark, far objects bright), flip invert_depth.
This one genuinely renders: it decodes your video, processes every frame through torch, and re-encodes (PyAV, no extra install). It's the slowest of the four stages here, and the cost scales with max_radius × layers - those two are where you budget.
The inputs that matter
- video - your clip (required,
COMFYTV_VIDEO). - depth_image or depth_video - at least one is required, and the node says so explicitly: "Z Defocus needs a depth map - wire a depth image or depth video (e.g. from Depth Anything)." A static image works for a locked-off shot; use a depth video if the camera or scene moves.
- focus_depth (0–1, default 0.5) and focus_range (0–1, default 0.15) - where the sharp plane sits and how wide it is. Tighten
focus_rangefor a more aggressive shallow-DOF look. - max_radius (1–48, default 16) and layers (3–12, default 8) - bokeh size and depth-slice count. Higher = smoother but slower.
- shape -
discorhexfor the bokeh kernel. Hexagon is the anamorphic-ish flex. - highlight_boost (0–3) and invert_depth - the "make highlights glow" and "flip near/far" switches.
The single video output goes downstream like any other stage.
Install and gotchas
Same install as every ComfyTV node - ComfyUI Manager (search "ComfyTV") or git clone https://github.com/jtydhr88/ComfyTV into ComfyUI/custom_nodes/, full restart. No extra Python deps for the stage itself; the only model involved is whatever you use to produce the depth map (a Depth Anything checkpoint in the usual ComfyUI depth-preprocessor slot).
The two ways people get stuck: forgetting the depth map entirely (you'll get the hard error above - it doesn't silently no-op), and picking layers=12 + max_radius=48 and wondering why a short clip takes minutes. Start at defaults, dial focus_range down for the shot, and remember: near-white means close in standard depth maps, so if your subject ends up blurred and the background sharp, invert_depth is your first move, not your last resort.
Inputs (13)
| 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. |
| focus_depth | FLOAT | 0.500–1 | — |
| focus_range | FLOAT | 0.150–1 | — |
| max_radius | INT | 161–48 | — |
| layers | INT | 83–12 | — |
| shape | COMBO | disc | 2 options: disc, hex |
| highlight_boost | FLOAT | 0.000–3 | — |
| invert_depth | BOOLEAN | false | — |
| videoopt | COMFYTV_VIDEO | — | |
| depth_imageopt | COMFYTV_IMAGE | — | |
| depth_videoopt | COMFYTV_VIDEO | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| video | COMFYTV_VIDEO | — |