
Single photo → white mesh → textured 3D character: full ComfyUI + Hunyuan3D-2 pipeline (+ the bugs that ate my weekend)
TL;DR: One 2D portrait → Hunyuan3D-2 in ComfyUI for geometry → Meshy for the final texture pass. Geometry from open-source is genuinely great even on a hard pose. Texture baking is the weak spot. Full node chain + the 4 bugs that cost me hours below.
Result
[img 1: source photo] → [img 2: white mesh] → [img 3: textured render]
Input was a single seated full-body portrait — crossed arms, crossed legs, long flowing hair, fabric draping over a stool. I deliberately avoided the "T-pose on white background" these models love, to see how it handles a real pose. It held up better than I expected.
Hardware: RTX 5090 (32GB). Geometry stage peaks well under that.
The pipeline
Stage 1 — Geometry (ComfyUI + Hunyuan3D-2, fully local)
Node chain:
LoadImage
→ background removal (TransparentBGSession+ / ImageRemoveBackground+)
→ ImageResize+ (960x960)
→ Hy3DModelLoader (hunyuan3d-dit-v2-0-fp16, attention_mode = sdpa)
→ Hy3DGenerateMesh (guidance 5.5, 50 steps)
→ Hy3DVAEDecode (mc surface extractor)
→ Hy3DPostprocessMesh (decimate to ~50k faces)
→ Hy3DExportMesh → white-mesh GLB
Raw decode landed around 333k verts / 1.3M faces, simplified down cleanly to 25k verts / 50k faces. The crossed legs, the hand against the cheek, the fabric folds — all reconstructed coherently from one view.
Stage 2 — Texture
Hunyuan3D-2 has a built-in texture path:
Hy3DMeshUVWrap
→ Hy3DRenderMultiView (render the white mesh from 6 angles)
→ Hy3DDelightImage (strip baked lighting)
→ Hy3DSampleMultiView (paint model generates per-view textures)
→ Hy3DBakeFromMultiview (project views back onto the mesh)
→ Hy3DMeshVerticeInpaintTexture / CV2InpaintTexture (fill seams)
→ Hy3DApplyTexture
→ Hy3DExportMesh → textured GLB
It works, but the multi-view projection left visible artifacts — red blotches where lip color and nail polish bled onto skin. Known limitation: the per-view colors don't always align perfectly during baking.
For the final asset I ran the mesh through Meshy. Texture alignment there is clearly cleaner — skin, hair, dress all came through without the bleed. Open-source geometry + commercial texture pass turned out to be the sweet spot for me.
The 4 bugs that cost me hours
1. A custom node globally monkey-patches PyTorch attention. An older Trellis integration node overwrites torch.nn.functional.scaled_dot_product_attention globally at import time. SageAttention only supports head dims 64/96/128, so Hunyuan3D's delight VAE (different head dim) crashes: AssertionError: headdim should be in [64, 96, 128] The fix is NOT patching source — that breaks on every update. Find the culprit and disable that node:
grep -rn "scaled_dot_product_attention\s*=" custom_nodes/
Disabling the offending node folder (rename to .disabled) stops the global pollution permanently.
2. White mesh vs textured mesh confusion. The workflow has TWO Hy3DExportMesh nodes — one geometry-only (intermediate), one textured. If the texture stage crashes partway, you still get the white-mesh GLB and assume "it ran but no color." Always confirm the SECOND export actually executed.
3. attention_mode is baked into shared workflow JSON. Workflows shared online store widget values, including attention_mode. If the original author had SageAttention installed, the JSON ships with attention_mode: sageattn. On a clean install that fails. Open Hy3DModelLoader, set it back to sdpa, re-save the workflow.
4. HuggingFace xet download fails behind some networks. Auto-download of the delight model died with a 401 from the xet CAS server. Workaround:
HF_HUB_DISABLE_XET=1
HF_ENDPOINT=https://hf-mirror.com # or your preferred mirror
Open source vs commercial — honest take
- Hunyuan3D-2 (open, free, local): geometry is excellent, fully self-hosted, nothing leaves your machine. Texture baking is the weak point — usable but artifact-prone.
- Meshy (commercial): texture + auto-rig is a clear tier above. Trade-off: subscription + uploading your input.
They're complementary. Portfolio/demo → open-source geometry is plenty. Polished deliverable → the commercial texture pass earns its keep.
Notes
- On RTX 5090 (sm_120 Blackwell) you need current PyTorch + CUDA — older prebuilt wheels won't load.
custom_rasterizerand the mesh painter extension need compiling from source; not hard, just setTORCH_CUDA_ARCH_LIST="12.0+PTX"first.
Happy to answer workflow questions in the comments.