CPA Depth
Who's In Front When Two People Share a Pixel
- plate
- depth
Overlap mode in this pack does something genuinely clever: it renders your subject and everyone else in the plate on the real plate, then subtracts the other people wherever they're in front. That subtraction needs an answer to a question segmentation can't always give - at this pixel, where a hand crosses a chest, which of these two people is the nearer one?
SAM 3 gives you masks, and where two people overlap, its masks are coarse. Often it hands the contested pixels to both of them, or to neither. CPA Depth is the tiebreak: a small monocular depth pass that says, per pixel, what's near and what's far.
How it works
One input, plate - the uint8 frame stack. One output, depth, a MASK where bright means near.
On first run it pulls Depth Anything V2 Small into models/depthanything/ (~99 MB, automatic, no manual download). Then per frame: run the processor and the model in float16 on the GPU, take predicted_depth, bicubic-interpolate it up to the frame's size, normalise min–max to 0–1, store as float16. The model is freed and the cache emptied at the end of the node, so it isn't sitting on VRAM for the rest of the render.
Small is the right call for this job, and it's also the only legal one here - Depth Anything V2's Base and Large weights are CC-BY-NC, and this pack is shipping to people doing client work. Small is Apache-2.0. The pack's credits say so explicitly, which is a nice bit of licence hygiene you rarely see.
The model does exactly what the KB says V2 does on video: it's a per-image network, so it works frame by frame and can flicker. That flicker doesn't survive into your matte, because the decision it feeds - in front or behind - gets voted over about 25 pixels and averaged over front_smoothing frames (default 3) so it can't pop.
Where the answer gets used
CPA Final takes the depth map plus the two attention-pass mattes and works out, at each contested pixel, whether the other person is in front. Depth decides only where SAM 3 is unsure; where SAM 3 sees exactly one person, that wins. Then the subtraction reaches occluder_reach pixels past the overlap to catch the soft edge of the person in front - fingertips, strand tips.
This is all under one switch on the main node: use depth for front/back, on by default when overlap mode is on. Turning it off is faster and, for shots without tricky overlaps, comparable. The pack's own warning about turning it off: fast thin fingers in front of the subject can ghost, because a local vote over SAM 3's coarse masks can't tell a fingertip from a shirt.
When it's wrong
A wrong front/back flip looks like a limb vanishing and reappearing, or a shoulder being cut off along a smooth line. Two fixes, in order:
front_smoothingup to 5 if the decision flips between frames. If depth genuinely can't tell - a hand at the same depth as the chest it's over - smoothing is the honest fix.- Turn the depth pass off if you see a confident wrong answer where SAM 3's masks are clean. Depth Anything is a relative-depth estimator, not a laser scan; on flat, low-texture regions it will occasionally decide the nearer person is the further one.
And a reminder that depth can't rescue the case it looks like it should: your subject's own arm resting on someone's shoulder really is at that person's depth. Depth will side with the other person, the subtraction will remove the arm, and the fix is a shift-click to add it back - one click, on a frame where it touches.
Install
Part of the pack - nothing to install for the node, and the weight downloads itself on the first overlap-mode run. If your ComfyUI has no network access, prefetch it:
hf download depth-anything/Depth-Anything-V2-Small-hf --local-dir ComfyUI/models/depthanything/Depth-Anything-V2-Small-hf
It needs transformers and huggingface_hub, both in the pack's requirements.txt:
cd ComfyUI/custom_nodes
git clone https://github.com/rik-python/ComfyUI-Comfy-Pro-Alpha-Generator.git
pip install -r ComfyUI-Comfy-Pro-Alpha-Generator/requirements.txt
As with every /internal node in this pack, it's hidden from the node menu and only appears in the graph the generator expands.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| plate | IMAGE | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| depth | MASK | — |