Nodes/Realistic Bokeh and Dreamy Look/Realistic Bokeh / Depth of Field (advanced)
ComfyUI Node

Realistic Bokeh / Depth of Field (advanced)

Bokeh that does the lens math, not just the blur

By marcsole96·Created 2 days ago·Updated 2 days ago· 0
Realistic Bokeh / Depth of Field (advanced)
  • image
  • depth_map
  • focus_mask
  • image
  • coc_map
  • focus_preview
bokeh_shapedisk
focus_modepoint
focus_depth0.500
focus_range0.15
focus_transition0.10
f_stop2.8
focal_length_mm50
sensor_width_mm36.0
blur_scale1.00
max_blur_px48
quality_layers12
blur_modelphysical
focus_spread1.00
focus_x0.500
focus_y0.500
depth_invertfalse
depth_modeinverse (disparity)
near_distance_m0.30
far_distance_m20.0
linear_lighttrue
highlight_bloomtrue
bloom_threshold0.75
bloom_gain4.0
edge_weight0.00
blades6
blade_curvature0.00
shape_rotation0
anamorphic_ratio2.00
star_points5
star_depth0.45
ring_thickness0.35
chromatic_aberrationfalse
ca_amount0.30
catseyefalse
catseye_strength0.60
catseye_grid4

Most depth-of-field nodes blur by depth and call it a day. Realistic Bokeh / Depth of Field (advanced), from ComfyUI-RealisticBokeh, is the one that does the optics: you give it a lens - f-stop, focal length, sensor size, focus distance - and it computes a real circle of confusion for every pixel. That's why an f/1.4 portrait lens and an f/8 landscape lens on the same image come out looking like different photographs. It's the bigger sibling of the pack's Easy Bokeh node, and the answer when "subject sharp, background soft" isn't specific enough for what you're chasing.

What makes it look real

The physics you actually get, from the pack's own documentation and source:

  • Linear-light processing - blur sums light energy rather than gamma-encoded values, which is how real lenses behave.
  • Highlight bloom - fakes the HDR a clipped 0–1 image lost, so bright out-of-focus points become glowing bokeh balls instead of grey mush. This is the single biggest realism win.
  • A physical circle of confusion from f_stop, focal_length_mm, sensor_width_mm and focus distance. Wider aperture and longer lens ⇒ shallower DOF, exactly like real life.
  • Depth-layered occlusion compositing - a blurred foreground bleeds over the in-focus subject, the thing cheap blur always gets backwards.
  • Shaped apertures - disk, polygon (aperture blades with blades and blade_curvature), anamorphic (vertical oval via anamorphic_ratio), star, heart, and ring (the mirror-lens donut). Convolution runs as FFTs on the GPU.

The inputs that matter

The plumbing is image + depth_map (resized automatically - depth from Depth Anything, MiDaS or any depth preprocessor). Then three outputs: image, plus coc_map (grayscale; black = in focus) and focus_preview (your image with the sharp region tinted green). Preview that last one - it's the fastest sanity check.

For beginners the set that does 90% of the work:

  • focus_mode - set to point (default) and put focus_x/focus_y on your subject. The node reads the depth at that point, so this is "tap to focus" and it's immune to whether your depth map is inverted. mask focuses on the median depth inside a connected focus_mask; the auto: nearest / farthest / center options are self-explanatory, though nearest/farthest do depend on depth_invert being right. manual is the fiddly old raw-slider way.
  • focus_range - the "subject won't go sharp" knob. A real fast lens has a focal plane millimetres deep, so only one slice of the subject is sharp and even the rest of a face blurs. That's physically correct and rarely what you want. Raise focus_range (a 0–1 band around the focus that stays fully sharp) until the green covers the subject - 0.2–0.5 is the usual landing zone.
  • f_stop and focal_length_mm - the lens. Lower f-stop / longer focal length = stronger blur. sensor_width_mm defaults to 36 (full frame); ~24 is APS-C. blur_scale is a master multiplier on top if you just want more or less.
  • blur_model - physical (the real CoC math) or artistic (the normalised depth-distance model the Easy node uses; more forgiving, less authentic).

Realism extras are all optional toggles: highlight_bloom (on by default - bloom_gain brightens the balls, bloom_threshold sets which highlights bloom), chromatic_aberration colour fringing, and catseye optical vignetting (bokeh squashes toward the frame edges like a real lens). Note catseye uses spatially-varying tiled convolution and is noticeably slower - catseye_grid is the quality knob.

The gotchas that will cost you an hour

Depth direction first. If focus lands on the wrong plane, toggle depth_invert - that's the single most common fix. The default is off, but many common depth maps (including, per the README, the usual Depth Anything/MiDaS output) have the subject bright and the background dark, which wants it on. In point mode the node reads the depth right at your focus point so it can't miss the plane entirely - but auto: nearest/farthest and the foreground-occlusion edges genuinely need depth_invert correct.

Second: razor-thin DOF is not a bug. If "the face is half blurry," don't fight the f-stop - that's a real 85mm f/1.4 rendering. Raise focus_range.

Third: speed. Cost scales with quality_layers (the number of depth slices - 10–16 is the sweet spot, higher = smoother but slower) and max_blur_px. For previews drop quality_layers to ~6 and disable catseye.

Install

ComfyUI Manager, search ComfyUI-RealisticBokeh, or by hand:

cd ComfyUI/custom_nodes
git clone https://github.com/marcsole96/ComfyUI-RealisticBokeh.git

Restart ComfyUI. No extra runtime dependencies - everything runs on the torch ComfyUI already ships. It lands under image/postprocessing.

Which node when

Use Easy Bokeh for "sharp subject, soft background" - it's the same engine with the physics hidden. Come here for the anamorphic oval, the mirror-lens ring, an honest f/1.4 falloff, or for matching a specific shot's look. The extra knobs pay off exactly as much as you're willing to tune them.

Categoryimage/postprocessing

Inputs (39)

NameTypeDefaultDescription
imageIMAGE
depth_mapIMAGE
bokeh_shapeCOMBOdisk6 options: disk, polygon, anamorphic, star, heart, ring
focus_modeCOMBOpoint6 options: manual, point, mask, auto: nearest, auto: farthest, auto: center
focus_depthFLOAT0.5000–1
focus_rangeFLOAT0.150–1
focus_transitionFLOAT0.100.001–1
f_stopFLOAT2.80.7–32
focal_length_mmFLOAT508–600
sensor_width_mmFLOAT36.04–70
blur_scaleFLOAT1.000–8
max_blur_pxINT481–200
quality_layersINT121–48
blur_modeloptCOMBOphysical2 options: physical, artistic
focus_spreadoptFLOAT1.000.1–4
focus_maskoptMASK
focus_xoptFLOAT0.5000–1
focus_yoptFLOAT0.5000–1
depth_invertoptBOOLEANfalse
depth_modeoptCOMBOinverse (disparity)2 options: linear, inverse (disparity)
near_distance_moptFLOAT0.300.05–100
far_distance_moptFLOAT20.00.2–1000
linear_lightoptBOOLEANtrue
highlight_bloomoptBOOLEANtrue
bloom_thresholdoptFLOAT0.750–1
bloom_gainoptFLOAT4.00–30
edge_weightoptFLOAT0.00-1–1
bladesoptINT63–12
blade_curvatureoptFLOAT0.000–1
shape_rotationoptFLOAT00–360
anamorphic_ratiooptFLOAT2.001–4
star_pointsoptINT53–12
star_depthoptFLOAT0.450.1–0.95
ring_thicknessoptFLOAT0.350.05–1
chromatic_aberrationoptBOOLEANfalse
ca_amountoptFLOAT0.300–1
catseyeoptBOOLEANfalse
catseye_strengthoptFLOAT0.600–1.5
catseye_gridoptINT42–10

Outputs (3)

NameTypeDescription
imageIMAGE
coc_mapIMAGE
focus_previewIMAGE