RunningHub Pixal3D Image to 3D
One image in, a textured 3D asset out
- pipe
- image
- mask
- asset
- camera_info
This is the node that actually does the thing. Feed it one image and it runs TencentARC's Pixal3D, an image-to-3D pipeline that reconstructs a textured, PBR-shaded 3D asset from a single photo or generated image. Everything else in the pack is plumbing around it: the loader feeds it a model bundle, and its asset output is what Save GLB turns into a file on disk.
What you're really getting
Set expectations before you spend an evening on the install. Image-to-3D is the one corner of 3D generation that genuinely works, and Pixal3D is among the best open entries in it - the community read it on release as a clear step up from raw TRELLIS.2. But "high-fidelity 3D asset" means aesthetic quality, not game-ready topology. You'll get a mesh with machine-generated triangle soup and UVs; it's brilliant for static props, renders, and 3D printing, and it is not rig-ready. If your destination is a game engine with animation, budget for a retopology pass.
Pixal3D also ships under a research license - academic use only, and explicitly "not intended for use within the European Union." Check the license before building anything commercial on it.
How the pipeline works
Pixal3D runs three flow-matching stages in sequence, and this node exposes every one of their knobs:
- Sparse structure (
ss_*) - sketches the coarse voxel scaffold of the object. - Shape SLAT (
shape_slat_*) - generates the structured latent that becomes the actual mesh. - Texture SLAT (
tex_slat_*) - paints the surface with PBR material channels.
That SLAT design is straight from the TRELLIS lineage - Pixal3D is built on that stack, right down to exporting through TRELLIS.2's o_voxel code. Before sampling, a MoGe model estimates the camera from your image, and the image is conditioned through DINOv3 features plus BiRefNet background removal and NAF upsampling - which is why the loader drags in five separate model folders. None of that is your problem; it all happens inside the node.
The inputs that actually matter
The required list is intimidating - 14 knobs - but you'll touch maybe three of them:
resolution:1024or1536. The generation grid size. 1024 is the sane default; 1536 buys detail and eats VRAM and time.ss_sampling_steps/shape_slat_sampling_steps/tex_slat_sampling_steps: the biggest quality-versus-speed levers. 12 is the shipped default. Drop all three to1for a smoke test - you'll know in a minute whether the pipeline works instead of waiting twenty.seed: reproducibility, and if a generation lands weird geometry, bumping it is the first thing to try.
Everything else - the per-stage guidance strengths, rescales, and rescale_t values - are CFG-style knobs; leave them at the tuned defaults. Two optional inputs are worth knowing: mask, which overrides the automatic background removal (wire in a MASK if the BiRefNet cutout is wrong), and max_num_tokens, the sparse-token cap for high-res stages - lower it if 1536 OOMs.
Outputs
asset(PIXAL3D_ASSET) - wire this intoRunningHub Pixal3D Save GLB; it carries the mesh and everything the exporter needs.camera_info(STRING) - the estimated camera parameters (angle, distance, mesh scale) as text, for downstream preview nodes.
Installing the whole stack
This node inherits the entire pack's weight. From the README:
cd ComfyUI/custom_nodes
git clone https://github.com/RH-RunningHub/ComfyUI_RH_Pixal3D.git
cd ComfyUI_RH_Pixal3D
pip install -r requirements.txt
The requirements file only pulls MoGe and huggingface_hub - the scary stuff is manual. NATTEN needs a matching wheel plus libnatten:
pip uninstall -y natten
pip install natten==0.21.6+torch2100cu128 -f https://whl.natten.org
python -c "import natten; print(natten.__version__, natten.HAS_LIBNATTEN)" # True
Then the CUDA extensions (flash_attn, flex_gemm, o_voxel, nvdiffrast, nvdiffrec_render) need wheels or source builds matched to your exact Python/PyTorch/CUDA. The README's install notes are the authority here - this is the corner where "it won't import" eats weekends.
The nodes never download models during execution. From your ComfyUI directory:
mkdir -p models/Pixal3D models/MoGe/moge-2-vitl models/DINOv3/dinov3-vitl16-pretrain-lvd1689m models/BiRefNet/RMBG-2.0 models/NAF
hf download TencentARC/Pixal3D --local-dir models/Pixal3D
hf download Ruicheng/moge-2-vitl --local-dir models/MoGe/moge-2-vitl
hf download facebook/dinov3-vitl16-pretrain-lvd1689m --local-dir models/DINOv3/dinov3-vitl16-pretrain-lvd1689m
hf download briaai/RMBG-2.0 --local-dir models/BiRefNet/RMBG-2.0
git clone https://github.com/valeoai/NAF.git models/NAF
curl -L -o models/NAF/naf_release.pth https://github.com/valeoai/NAF/releases/download/model/naf_release.pth
The README's tested target is a 24 GB GPU with low_vram=true at 1024; people have squeezed it onto 8 GB with the 1024 cascade, but don't count on it.
Common issues
- First run feels frozen. It loads the full pipeline plus five aux models - give it a minute or two before judging.
- Instantly fails on the loader with "not found" - a model folder is missing or in the wrong place; the error names the exact path.
- OOM at 1536 - drop to 1024, lower
max_num_tokens, or turn onlow_vramat the loader. - Bad background cutout - supply your own
maskinstead of fighting the auto-segmentation.
The workflow JSON in examples/ wires LoadImage → Load Model → this node → Save GLB. It ships with pai.jpg; drop your own image in and go.
Inputs (21)
| Name | Type | Default | Description |
|---|---|---|---|
| pipe | PIXAL3D_PIPE | — | |
| image | IMAGE | — | |
| seed | INT | 420–2147483647 | — |
| resolution | COMBO | 1024 | 2 options: 1024, 1536 |
| ss_guidance_strength | FLOAT | 7.50–30 | — |
| ss_guidance_rescale | FLOAT | 0.700–1 | — |
| ss_sampling_steps | INT | 121–100 | — |
| ss_rescale_t | FLOAT | 5.00.1–20 | — |
| shape_slat_guidance_strength | FLOAT | 7.50–30 | — |
| shape_slat_guidance_rescale | FLOAT | 0.500–1 | — |
| shape_slat_sampling_steps | INT | 121–100 | — |
| shape_slat_rescale_t | FLOAT | 3.00.1–20 | — |
| tex_slat_guidance_strength | FLOAT | 1.00–30 | — |
| tex_slat_guidance_rescale | FLOAT | 0.000–1 | — |
| tex_slat_sampling_steps | INT | 121–100 | — |
| tex_slat_rescale_t | FLOAT | 3.00.1–20 | — |
| maskopt | MASK | — | |
| mesh_scaleopt | FLOAT | 1.000.1–10 | — |
| extend_pixelopt | INT | 0-256–256 | — |
| camera_image_resolutionopt | INT | 512128–2048 | — |
| max_num_tokensopt | INT | 491524096–262144 | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| asset | PIXAL3D_ASSET | — |
| camera_info | STRING | — |