Pixal3D: Image to Mesh
One image, one queue, a PBR mesh — Pixal3D without the pain
- image
- mask
- pipeline_ready
- mesh
- preprocessed_image
- camera_angle_x
- distance
- glb_path
This is the node that turns one image into a textured, PBR-ready 3D mesh - and earns its keep by making something genuinely miserable into something you just queue.
Pixal3D is Tencent ARC + Tsinghua's SIGGRAPH 2026 model - one image in, a GLB with real PBR textures out, in about 3–5 minutes on a modern RTX card. Running the raw repo is a gauntlet: people documented the Blackwell kernel builds, the natten dance, and a lot of yelling at Claude to get it going. This wrapper sidesteps all of that - it installs into ComfyUI's own Python and you never touch a terminal past the setup. People who've run Trellis.2 call Pixal3D a real step up: it back-projects pixel features into 3D instead of loosely injecting them through attention.
How it works
The pipeline is longer than you'd guess from the single input socket. Roughly: your image gets its background removed by BiRefNet (the MIT remover ComfyUI itself shipped in core), then smart-cropped and composited onto a background color. MoGe-2 estimates camera intrinsics, four DINOv3 extractors project conditioning features into 3D, and a cascade of sampler stages builds the sparse structure, the shape, and the texture - finishing with mesh extraction, a PBR bake, decimation, and GLB export.
The part that will bite you isn't the AI - it's memory: a ~24 GB weight set, and a ~14 GB resident pipeline once loaded.
The inputs that matter
Most of the widget list is "leave it alone" - the defaults are tuned. You'll actually touch these:
image- your photo. Only the first batch entry is used, so don't feed it a batch.pipeline_type-1024_cascade(default, recommended) or1536_cascade(heavier, marginally better, needs a 34 GB-class card).seed- same seed and settings give you the same mesh, handy for iterating on one parameter.max_num_tokens- the HR token budget, and your main VRAM dial. Default 49152 ≈ 9 GB of activations. If you're on a 16 GB card, dropping this to 32768 or 24576 is the first thing to try before you OOM.low_vram- offloads submodels to CPU between stages. Slower, but the difference between fitting and not.background_color- keep itgray. The tooltip spells out why:blackbakes thin black silhouette lines into the PBR texture. That's the classic "why do my meshes have dark streaks" fix.keep_warm-trueby default, so the ~14 GB pipeline stays in VRAM and the next run is ~3 minutes instead of a 7–10 minute cold load. Flip it off when you want that memory back.
There are also ss_/shape_/tex_ guidance widgets and camera overrides; setting both camera_angle_x_override and distance_override above zero skips MoGe and forces your own camera - useful for retrying a run that came out geometrically off.
What you get out
Five outputs, and you'll use two:
mesh(TRIMESH) - wire into aPreview3Dnode to look at it.glb_path(STRING) - the absolute path of the auto-saved file. You can chain this straight intoPreview3Dand skip the explicit export step.preprocessed_image- the cropped/composited image that actually went in, handy for debugging a bad mask.camera_angle_x/distance- the camera values MoGe actually estimated, which you can feed back as overrides on a retry.
The GLB (plus an optional OBJ if you flip save_obj) lands in ComfyUI/output/pixal3d_<timestamp>_<seed>.glb with PNG textures - Blender, Three.js, any standard viewer.
Installing it
ComfyUI Manager is the easy path: search ComfyUI-Pixal3D, install, restart - the plugin's install.py runs automatically and drops everything into ComfyUI's own Python, no separate worker env. Manual route:
cd $HOME\Documents\ComfyUI\custom_nodes
git clone https://github.com/dreamrec/ComfyUI-Pixal3D.git
cd ComfyUI-Pixal3D
& "$HOME\Documents\ComfyUI\.venv\Scripts\python.exe" install.py
Then restart. The hard requirements: Windows 10/11 x64, Python 3.12, PyTorch 2.8 + CUDA 12.8 (the ComfyUI Desktop defaults), an NVIDIA RTX 30/40/50 with ≥16 GB VRAM (24 GB+ recommended), and ~50 GB of disk - the first queue downloads ~26 GB of weights from HuggingFace. No AMD/Intel GPUs; upstream Pixal3D is CUDA-only. And note the license: the wrapper is MIT, but the Pixal3D model itself is academic / non-commercial only and explicitly not for use in the EU.
Where people get burned
- Black lines baked into the texture - an old saved workflow with
background_color: black. Re-create the node from the menu; the default isgray. - OOM - drop
max_num_tokensto 32768/24576, enablelow_vram, or step down to1024_cascade. - VRAM fragmentation after many runs - the README documents ten consecutive warm runs succeeding and the eleventh OOMing. Queue
Pixal3D: Free Pipelinebetween batches to defrag.
If the run itself dies with Repository Not Found on a HuggingFace URL or a device-resync after toggling low_vram, you're on an old plugin version - git pull, re-run install.py, restart.
Inputs (31)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | Input image (RGB). Single image; first batch entry is used. | |
| pipeline_type | COMBO | 1024_cascade | 1024_cascade is recommended; 1536_cascade is heavier and may overflow VRAM. |
| seed | INT | 420–2147483647 | — |
| maskopt | MASK | Foreground mask (white=object). If provided, BiRefNet is skipped. | |
| pipeline_readyopt | PIXAL3D_PIPELINE_READY | — | |
| low_vramopt | BOOLEAN | false | Only used if pipeline_ready is not connected. |
| max_num_tokensopt | INT | 4915216384–131072 | HR token budget. Lower = less VRAM, smaller mesh. 49152 ~= 9GB activations. |
| mesh_scaleopt | FLOAT | 1.00.1–5 | — |
| image_resolutionopt | INT | 512256–2048 | — |
| camera_angle_x_overrideopt | FLOAT | 0.0000–3.14 | 0 = auto (MoGe-2). Set both override fields > 0 to skip MoGe. |
| distance_overrideopt | FLOAT | 0.000–50 | — |
| ss_guidance_strengthopt | FLOAT | 7.51–20 | — |
| ss_sampling_stepsopt | INT | 121–50 | — |
| ss_guidance_rescaleopt | FLOAT | 0.700–1 | — |
| ss_rescale_topt | FLOAT | 5.00–10 | — |
| shape_guidance_strengthopt | FLOAT | 7.51–20 | — |
| shape_sampling_stepsopt | INT | 121–50 | — |
| shape_guidance_rescaleopt | FLOAT | 0.500–1 | — |
| shape_rescale_topt | FLOAT | 3.00–10 | — |
| tex_guidance_strengthopt | FLOAT | 1.01–20 | — |
| tex_sampling_stepsopt | INT | 121–50 | — |
| tex_guidance_rescaleopt | FLOAT | 0.000–1 | — |
| tex_rescale_topt | FLOAT | 3.00–10 | — |
| decimation_targetopt | INT | 2000005000–1000000 | — |
| texture_sizeopt | INT | 2048256–4096 | — |
| remeshopt | BOOLEAN | true | — |
| background_coloropt | COMBO | gray | Color composited behind the foreground mask. Default 'gray' (128,128,128) prevents dark-silhouette bleed that bakes thin black lines into the PBR texture; 'black' matches Pixal3D inference.py defaults but causes those artifacts; 'white' for light-on-dark subjects. |
| keep_warmopt | BOOLEAN | true | True: keep the loaded Pixal3D pipeline in VRAM after this run (~14 GB) so the NEXT call is fast (~3 min instead of ~7-10 min cold-load). False: auto-free the pipeline at the end of THIS call. Use False if you're done with Pixal3D for a while and need that VRAM back for other nodes. |
| save_to_output_diropt | BOOLEAN | true | When True, auto-save the GLB to ComfyUI/output/<prefix>_<unix_ns>_<seed>.glb. Disable for chained workflows that export downstream via another node — leaves the mesh in memory only. |
| output_filename_prefixopt | STRING | pixal3d | Prefix for the auto-saved GLB filename. Final name: <prefix>_<unix_ns>_<seed>.glb. Ignored if save_to_output_dir=False. |
| save_objopt | BOOLEAN | false | Also export an OBJ (+ .mtl + texture PNGs) alongside the GLB. OBJ is base-color-only (the format has no standard metallic/roughness slots) — keep the GLB as the canonical PBR artifact and use the OBJ for DCC tools that prefer it (Blender, ZBrush, Marmoset). Ignored if save_to_output_dir=False. |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| mesh | TRIMESH | — |
| preprocessed_image | IMAGE | — |
| camera_angle_x | FLOAT | — |
| distance | FLOAT | — |
| glb_path | STRING | — |