Pixel Perfect Depth (Unpack Depth)
Don't re-run the model to tweak a depth map — unpack it
- ppd_depth
- depth_image
- depth_mask
If you've used the pack's depth-map node, you've noticed it hands you two things: a pretty colorized image and a ppd_depth payload that only this pack's nodes understand. PPDDepthUnpack is the decoder ring - it takes that payload and turns it into plain, reusable ComfyUI types: an IMAGE and a MASK. It's the node you reach for when the depth is done and you want to do something with it, without paying for another diffusion pass to change how it looks.
Why it exists
The depth-map node already outputs a displayable depth_image, so why unpack? Three reasons.
First, control without re-inference. Invert the depth, force grayscale, re-normalize, or colorize - the original node bakes those choices in at generation time, so changing your mind means re-running the whole diffusion model. This node applies the same transforms to the already-computed float32 depth, in milliseconds.
Second, a MASK output. ComfyUI's mask type is what ControlNet preprocessors and a lot of image-compositing nodes actually want. Invert the map, feed it as a mask, and "near" and "far" become soft selection tools. The depth-as-mask trick is genuinely useful for controlling where effects apply based on distance from the camera.
Third, resolution. The payload holds depth at full float precision, so unpacking gives you the exact map without the 8-bit quantization the display path round-trips through.
What it does
Inputs:
ppd_depth- the PPD_DEPTH payload from any depth-map or video-depth node in the pack.normalize(default on) - remaps the raw depth to 0–1 using its own min/max. Turn it off if you want the true raw values (they're relative scale, so mostly useful for debugging).invert(default off) - flips near/far. Standard depth maps are white-close, black-far; invert when your downstream tool expects the opposite.colorize(default off) - applies the Spectral colormap. The depth-map node colors by default; here it's off, because you'll usually want clean values to work with.
Outputs:
depth_image- IMAGE, the map as three identical grayscale (or colored) channels.depth_mask- MASK, the same values as a single-channel mask.
Both are normalized to 0–1 (when normalize is on), so they're interchangeable with any depth output in the ecosystem - you can feed the mask straight into a depth ControlNet or into a compositing node that expects a mask input.
Where it sits in a workflow
The typical chain is: PPDDepthMap → ppd_depth into PPDDepthUnpack → depth_mask into your ControlNet or into the pack's point-cloud node. Or run the video node and unpack the per-frame payload the same way. Because it only touches the payload, it costs nothing and you can afford to branch it - one copy for ControlNet, one inverted for a foreground mask, one colorized for a preview.
Install and gotchas
It's part of the one-pack family, so install once and you have all seven nodes:
cd ComfyUI/custom_nodes
git clone https://github.com/Apache0ne/ComfyUI-pixel-perfect-depth
cd ComfyUI-pixel-perfect-depth
pip install -r requirements.txt
Then restart ComfyUI, and if you haven't already, drop the pack's weights into ComfyUI/models/ComfyUI-pixel-perfect-depth/ - Unpack itself needs no models, but it won't run until a depth node upstream has. (ComfyUI Manager users: search ComfyUI-pixel-perfect-depth.)
The only real footgun: ppd_depth is a pack-private type. You can't fake one from a regular image, and if you disconnect it you get a type mismatch error, not a helpful hint. Keep the source node wired and this node stays boring - which is exactly what you want a utility node to be.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| ppd_depth | PPD_DEPTH | — | |
| normalize | BOOLEAN | true | — |
| invert | BOOLEAN | false | — |
| colorize | BOOLEAN | false | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| depth_image | IMAGE | — |
| depth_mask | MASK | — |