ProjectPointCloud
Turning an N×7 cloud back into an image you can actually look at
- pointcloud
- image
- mask
- depth
Every point cloud in this pack eventually needs to become something you can see. ProjectPointCloud is the renderer for that: it takes an N×7 cloud (xyz + RGB) and rasterizes it into an image, a coverage mask, and a depth map - in pinhole, fisheye, or equirectangular projection. It's the viewfinder for the whole point-cloud side of camera-comfyUI.
This is the node that makes "fly through a point cloud" workflows work. You load or build a cloud, hand it a projection and a field of view, and out comes an image of the scene from that camera. Move the camera (TransformPointCloud or a trajectory) and re-project, and you've got a fly-through. The pack's pointcloud_walker.json workflow is literally this: image → depth → cloud → cleaned → projected along a recorded trajectory into a WEBM. It also underpins the enrichers, which project a cloud to see where the holes are before filling them.
How it works
It's a GPU z-buffer projection: points are transformed and dropped into pixels, nearest wins for color, and a second-layer depth buffer catches what's hidden behind the front surface. Then it does real work on the holes - an iterative ring-fill that grows the foreground into rear-only gaps, plus a depth-aware closing pass that only fills small flat holes (so it doesn't smear across genuine depth jumps). With point_size above 1, splats are dilated and averaged to fill sparse coverage, giving chunkier but smoother splats.
The inputs
- pointcloud -
N×7cloud, xyz + RGB. - output_projection - PINHOLE / FISHEYE / EQUIRECTANGULAR.
- output_horizontal_fov - degrees; default 90.
- output_width / output_height - resolution of the projected view.
- point_size - default 1; raise to 2–3 for sparser clouds so points fill pixels instead of pinholes.
- return_inverse_depth - default false; flip it to get 1/depth out instead of raw depth (handy if downstream expects inverse depth).
What comes out
- image -
[1,H,W,3]RGB render. - mask -
[H,W], 1.0 where the cloud covered the pixel. - depth -
[1,H,W,1]depth (or inverse depth), masked where there's no coverage.
Feed the image into a SaveImage, or chain image + mask into outpainting (that's exactly what PointcloudTrajectoryEnricher does internally).
Installing it
Part of camera-comfyUI. Manager → Custom Nodes Manager → camera-comfyUI → Install → restart, or:
cd ComfyUI/custom_nodes
git clone https://github.com/Alexankharin/camera-comfyUI.git
cd camera-comfyUI && python install.py
No optional dependencies.
Common issues
- Image looks like Swiss cheese - cloud too sparse for the resolution. Raise
point_size, lower the output resolution, or clean/denoise the cloud upstream. - Holes that shouldn't be there - the depth-aware closing is deliberately conservative to avoid filling across depth jumps; points behind an occluder stay holes. That's the right call most of the time.
- Only points in front render - correct: the node drops points behind the camera (
z <= 0). Transform your cloud if you want the other side.
Project it, look at it, fix it - repeat.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| pointcloud | TENSOR | — | |
| output_projection | COMBO | 3 options: PINHOLE, FISHEYE, EQUIRECTANGULAR | |
| output_horizontal_fov | FLOAT | 90.00 | — |
| output_width | INT | 5121–16384 | — |
| output_height | INT | 5121–16384 | — |
| point_size | INT | 1 | — |
| return_inverse_depth | BOOLEAN | false | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| mask | MASK | — |
| depth | TENSOR | — |