ComfyUI Node

Z Depth

Turn a renderer's Z-depth EXR into a usable depth map

By Conor-Collins·Created 2 years ago·Updated about a year ago· 33
Z Depth
    • Normalized_Depth_Image
    exr_path
    min_depth0.00
    max_depth1.00

    If you've ever rendered a Z-depth pass in Blender, Cycles, Arnold, or any real 3D package, you know the problem: the file comes out as a floating-point EXR that ComfyUI can't just slurp in. Z Depth (class ZDepthNode) is the bridge. Point it at that EXR, give it the depth range you care about, and it hands you a normalized grayscale image ready for ControlNet conditioning, displacement, parallax, or compositing.

    Depth maps are one of those capabilities that unlock a whole category of output - the KB essay on depth estimation spells out the uses: ControlNet conditioning to constrain a regen to the same spatial structure, 3D parallax "living photo" effects, displacement geometry, even meshes. A renderer's Z pass is the accurate source for all of it, because it's real geometry rather than an estimated guess. This node is how that precision gets into the graph.

    How it works

    Three inputs:

    • exr_path - the path to your Z-depth EXR file
    • min_depth (default 0) and max_depth (default 1) - the range of depth values you want mapped

    The mechanism is normalization: it loads the EXR's float depth data and remaps the values between min_depth and max_depth down to the 0–1 range that grayscale images use. Values below the floor clamp to black, above the ceiling to white. The output is Normalized_Depth_Image (IMAGE), a single grayscale map you can wire anywhere an image goes.

    The range inputs matter more than they look. If your scene's depth spans, say, 0 to 50 units, leaving max_depth at 1 means nearly everything clamps to white and you get a useless map. Set max_depth to your scene's far distance and the gradient actually spreads across the image.

    Where it fits

    Depth ControlNet is the big one - take your render's real Z pass, feed it to a depth ControlNet, and regenerate the same composition in a new style with the structure locked in. Beyond that: displacement maps for 3D printing or mesh work, parallax effects, or depth-based compositing where you cut and blend by distance.

    Here's the honest caveat, and it's a real one. EXR Z-depth is 32-bit float; this node normalizes it down to an 8-bit grayscale image, and that loses fine precision. The community ran into exactly this when piping depth maps out of ComfyUI - people wanting displacement maps asked for >8-bit output and got quantization. If your depth goes into a displacement or measurement workflow where precision matters, the better path is the author's successor pack, ComfyUI-CoCoTools_IO, which has a Z Normalize node that keeps more of the range and can save back out as EXR. For ControlNet conditioning - which happily eats 8-bit grayscale - this node is completely fine.

    Installing it

    This node lives in ComfyUI-CoCoTools, which is deprecated: the README marks it unmaintained and redirects to the successor repo above, and the original repo URL has been 404ing on GitHub since at least August 2026. That's a good sign this specific node is better sourced from the successor, which carries the Z-normalize work forward. If you still want this pack, install via ComfyUI Manager (search ComfyUI-CoCoTools) or manually:

    cd ComfyUI/custom_nodes
    git clone https://github.com/Conor-Collins/coco_tools
    

    Then the requirements (Windows portable, from python_embeded/):

    python.exe -m pip install -r ./ComfyUI/custom_nodes/ComfyUI-CoCoTools/requirements.txt
    

    Restart ComfyUI afterward. Note the requirements pull in OpenImageIO, which is the heavy dependency behind all the EXR handling here - on Windows portable it installs into the embedded Python, so run the pip line from that environment, not your system Python.

    Gotchas

    • Depth convention varies by renderer. Some packages write white = near, others white = far. If your ControlNet result comes out inverted (depth feeling reversed), flip the image before it goes into the ControlNet.
    • Set max_depth to your scene's actual far depth, not the default 1, or the map crushes to near-white.
    • Watch for the 8-bit precision loss described above if you're doing displacement rather than conditioning.
    • The pack is abandoned. For regular EXR depth work, go straight to the successor repo - it's where this feature actually lives now.
    CategoryCOCO Tools/Loaders

    Inputs (3)

    NameTypeDefaultDescription
    exr_pathSTRING
    min_depthFLOAT0.00
    max_depthFLOAT1.00

    Outputs (1)

    NameTypeDescription
    Normalized_Depth_ImageIMAGE