Compute Defocus Map
Turning depth into a per-pixel blur recipe
- disparity_map
- focus_point
- defocus_preview
- defocus_map
- defocus_raw
ComputeDefocusMap is where the refocus pipeline stops being about depth and starts being about blur. It takes a disparity/depth map and a focus point and computes, for every pixel, exactly how much it should be blurred based on its distance from the focal plane. The formula is gloriously simple:
blur = K × |depth − depth_at_focus|
where K is blur_strength, depth is the (normalized) depth at each pixel, and depth_at_focus is the depth value at your selected focus point. Everything at the focus depth gets blur 0 - perfectly sharp. Everything else gets blur proportional to how far it is in depth, capped at max_coc (the maximum circle of confusion, the blur-radius ceiling in real-photography terms). That one formula is the entire artistic control surface of the pack.
The three outputs, and why you should care which is which
- defocus_preview - contrast-stretched to full 0–1 for visualization. This is what you look at.
- defocus_map - the real normalized map, clamped at max_coc. This is what you feed to bokeh generation.
- defocus_raw - the raw blur values before normalization. For debugging.
Mixing them up is the classic wiring error - the bokeh nodes want defocus_map, not the pretty preview.
The knobs that make the photograph
- blur_strength (20) - K, how fast blur grows with depth difference. Subtle portrait: 10–20. Standard bokeh: 20–30. Dramatic tilt-shift: 40–60. Extreme shallow-DOF: 60–100.
- max_coc (100) - the blur cap. 64 = gentle softening; 100+ = obvious separation; 200+ = very shallow DOF look.
- use_raw_disparity (false) - if your input is unnormalized raw depth values instead of normalized 0–1, flip this. Default expects normalized.
- normalize_for_genfocus (false) - the one that surprises people. The original Genfocus does not stretch its defocus map to full 0–1 - dark maps are the trained convention, and subtle bokeh is normal. If your map looks nearly black, that's often correct. Turn this on only if you want a stronger/different effect; it's explicitly experimental.
Where the inputs come from
disparity_map is typically the disparity_map or depth_map output from DepthPro Estimate (in relative mode), and focus_point comes from Select Focus Point or Focus Point From Mask. The output defocus_map feeds either Genfocus Bokeh (Native) directly or Genfocus Defocus Map Condition if you're driving Genfocus Generate yourself.
A reality check on "no change"
Even if your focus point matches the original photo's focus, bokeh generation will still slightly soften already-sharp areas - FLUX re-renders, and tiny depth differences still produce small blur values. If you want truly zero change in sharp regions, your defocus map has to be genuinely zero there; the preview output is how you verify.
Install
Part of the Refocus pack (ComfyUI Manager → "Refocus - Generative Refocusing", or clone into custom_nodes/). No models, no pip extras - pure numpy math. It works even before you commit to the FLUX download, which makes it the cheapest node in the pack to learn on.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| disparity_map | IMAGE | — | |
| focus_point | FOCUS_POINT | — | |
| blur_strengthopt | FLOAT | 20.00–100 | K value - controls bokeh intensity (0 = no blur) |
| max_cocopt | FLOAT | 1001–500 | Maximum circle of confusion (blur radius) |
| use_raw_disparityopt | BOOLEAN | false | If True, expects raw disparity values. If False, expects normalized 0-1 depth. |
| normalize_for_genfocusopt | BOOLEAN | false | If True, stretch defocus map to full 0-1 range for stronger bokeh. Original Genfocus uses False. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| defocus_preview | IMAGE | — |
| defocus_map | IMAGE | — |
| defocus_raw | IMAGE | — |