EDou 3D Pipeline — Hunyuan3D-2.1 PBR + Unity glTFast
Pipeline de produção pra geração de assets 3D PBR (mahogany + dourado, baroque) do projeto e-DOU VR Library (Unity 6.4 + Meta Quest 3) via:
- SDXL → imagem de referência (1024×1024)
- Hunyuan3D-2.1 (Tencent) — shape + UV-baked PBR paint
- glTFast — drop GLB direto no Unity, sem Blender/FBX
Validado em 2026-04-29 com 2 estantes hero piece (mahogany + gilded) renderizadas
fotorealisticamente no Unity 6.4.4f1 com URP. Custo total: $0.15 numa RTX 3090
Vast.ai (30min). Tempo por estante: ~2min de paint pipeline.
⚠️ Por que NÃO usar o pipeline antigo (FBX)
Versão anterior (add_estante_anchors.py + Blender export FBX) NÃO funciona
com Hunyuan3D-Paint v2.1: o material do GLB tem Mix node entre Image Texture e
Principled BSDF que o exporter FBX do Blender NÃO traduz, resultando em FBX sem
textura (mesh aparece cinza no Unity). Rodar bash setup/run_estante_pipeline.sh
no formato anterior também fazia o paint v2.1 falhar silenciosamente — chamava
Hunyuan3DPaintPipeline.from_pretrained(...subfolder="hunyuan3d-paintpbr-v2-1")
que resolve pra pipeline v2.0 (KeyError swallowed), nunca executando o passo de
paint.
Solução atual: invocar textureGenPipeline.py PBR diretamente +
importar GLB no Unity via com.unity.cloud.gltfast (oficial Unity 6+).
Quick start
1. Spin RTX 3090 em Vast.ai (~$0.25/hr)
# SSH no instance (dentro de tmux SEMPRE)
tmux new -s paint
git clone https://huggingface.co/<your-user>/edou-3d.git
cd edou-3d
# Setup (~15min, ~$0.06)
bash setup/install_hunyuan3d.sh # 8 patches obrigatórios + deps + ckpts
2. Gerar estante PBR (~2min, ~$0.02 por mesh)
# Coloca tua imagem SDXL em /tmp/input.png (ou usa um SDXL render pronto)
python3 workflows/run_paint_pbr.py \
--image /tmp/input.png \
--output-dir /tmp/out/
# Output:
# /tmp/out/shape.glb — mesh sem textura
# /tmp/out/textured_pbr.glb — UV-baked PBR (←drop em Unity)
# /tmp/out/textured_pbr.jpg — albedo 2048×2048 standalone
3. No laptop: download GLB + drop em Unity
scp -P <PORT> -i ~/.ssh/<key> \
root@<vastai-ip>:/tmp/out/textured_pbr.glb \
./outputs/<asset-name>.glb
# Copia direto pra Unity Assets/
cp ./outputs/<asset-name>.glb \
<unity-project>/Assets/_Project/Models/Furniture/
# Unity importa nativamente via com.unity.cloud.gltfast (já instalado).
# AssetDatabase.LoadAssetAtPath<GameObject>(glbPath) retorna prefab pronto.
4. Em Unity, ground + scale runtime
Hunyuan3D output vem normalizado em bbox [-1, +1] (centro na origem). Pra colocar no chão e dimensionar pra altura "hero" (ex: 2.6m):
var go = (GameObject)PrefabUtility.InstantiatePrefab(
AssetDatabase.LoadAssetAtPath<GameObject>(glbPath));
var renderers = go.GetComponentsInChildren<MeshRenderer>();
var b = renderers[0].bounds;
foreach (var r in renderers.Skip(1)) b.Encapsulate(r.bounds);
float scale = 2.6f / b.size.y;
go.transform.localScale = Vector3.one * scale;
// Ground: shift Y baseado em min Y dos 8 cantos transformados de cada mesh.
// (Renderer.bounds só atualiza no próximo frame em Editor — calcular manual)
float minY = renderers
.SelectMany(r => Get8Corners(r.GetComponent<MeshFilter>().sharedMesh.bounds, r.transform))
.Min(c => c.y);
go.transform.position += Vector3.up * -minY;
Implementação completa: EstanteAIPreviewScene.SpawnFBX no Unity project EDou.
Estrutura do repo
3d-pipeline/
├── README.md este arquivo
├── setup/
│ ├── install_hunyuan3d.sh ⭐ install com 8 patches obrigatórios
│ ├── download_models.sh [legado — Hunyuan baixa weights via HF cache]
│ ├── verify_install.sh smoke test
│ └── run_estante_pipeline.sh [LEGADO — usa pipeline v2.0, falha silenciosamente]
├── workflows/
│ ├── run_paint_pbr.py ⭐ shape + paint v2.1 PBR standalone
│ ├── hunyuan_inference.py [legado — caminho v2.0]
│ └── sdxl_estante.json ComfyUI SDXL workflow
├── prompts/
│ ├── estante_baroque.txt SDXL prompt pra estantes ornamentadas
│ ├── casco_hogwarts.txt SDXL prompt pro casco (paredes/teto/vitrais)
│ └── README.md guia de prompt engineering
├── blender/
│ └── add_estante_anchors.py [LEGADO — FBX export bug com Hunyuan2.1
│ Mix nodes; usar glTFast direto no Unity]
├── docs/
│ ├── vastai_runbook.md SSH + tmux + custo
│ ├── troubleshooting.md ⭐ 8 patches catalogados + lições
│ └── cost_tracking.md log de runs reais
├── extract_glb_textures.py utility pra debugar GLB internals
└── outputs/ gitignored — gerados
Os 8 patches obrigatórios
Sem esses patches, paint v2.1 falha silenciosamente. Detalhes em
docs/troubleshooting.md. Resumo:
- Repo correto: clone
github.com/Tencent-Hunyuan/Hunyuan3D-2.1(não o repoHunyuan3D-2antigo). HFtencent/Hunyuan3D-2.1é só weights. mesh_utils.py: lazyimport bpy+convert_obj_to_glbvia trimesh (bpy não tem wheel pra Python 3.12).simplify_mesh_utils.py:fast_simplification 0.1.13mudou APItarget_count→target_reduction. Patch inline no install.- Compile inpaint:
cd hy3dpaint/DifferentiableRenderer && bash compile_mesh_painter.sh - Build custom_rasterizer:
cd hy3dpaint/custom_rasterizer && pip install --no-build-isolation . - Torch ≥ 2.6 (transformers 4.57+ exige por CVE-2025-32434) + bypass CUDA version check (Vast.ai instances têm CUDA 13 toolkit, torch 2.6 vem CUDA 12.4).
setuptools < 81(pkg_resources removido em 81+, pytorch-lightning 1.9.5 ainda usa).- RealESRGAN ckpt download manual:
wget https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth
Pipeline conceitual
SDXL prompt (Anderson) ── ComfyUI/text2img ──→ reference.png (1024×1024)
│
Hunyuan3DDiTFlowMatchingPipeline ←─────────────────────┘
↓ (~1min, RTX 3090)
shape.glb (mesh sem textura, ~30MB)
↓
Hunyuan3DPaintPipeline (PBR v2.1) ←── reference.png
↓ (~80s, RTX 3090, multiview diffusion + UV bake)
textured_pbr.glb (mesh + UV-baked albedo 2048×2048, ~1.4MB)
↓ scp pra local
Unity Assets/_Project/Models/Furniture/<name>.glb
↓ Unity import (com.unity.cloud.gltfast)
Prefab with mesh + material + texture wired
↓ runtime scale + ground baseado em bounds
Hero piece in scene ✓
Validação 2026-04-29
| Asset | Tempo gen | Tamanho GLB | Status Unity |
|---|---|---|---|
| Estante A (mahogany) | 71.8s | 1.4 MB | ✅ Render perfeito (mahogany + dourado UV-baked) |
| Estante B (gilded) | 71.8s | 1.4 MB | ✅ Render perfeito (mahogany + dourado mais elaborado) |
Custo total: $0.10. Cf. docs/cost_tracking.md.
Custo esperado pra uso recorrente
| Tarefa | Tempo | Custo |
|---|---|---|
| Setup primeira vez (instance fresh) | ~15min | ~$0.06 |
| Gen 1 asset (shape + paint) | ~2-3min | ~$0.02 |
| Gen 10 assets em sessão | ~25min | ~$0.10 |
| Setup + 10 assets numa sessão | ~40min | ~$0.16 |
Sempre destruir instance pós-uso (vast.ai/console → Destroy). Esquecer = $/hr.
Requisitos
- Vast.ai conta com saldo (>$2 recomendado)
- GPU mínimo: 24 GB VRAM (RTX 3090 / 4090 / A5000 / A40 / A100)
- Storage: ~50 GB no instance
- Local: Unity 6.4+ com
com.unity.cloud.gltfastpackage - (Opcional) Blender 5.x se quiser inspecionar GLB localmente
Licenças
- Scripts deste repo: MIT
- Hunyuan3D-2.1: Tencent Hunyuan License Agreement (não-comercial; ver
LICENSEno repo Tencent) - SDXL: CreativeML Open RAIL-M
- Assets gerados (GLBs PBR): livre conforme licença Tencent — verificar caso a caso
Próximos passos
- Cleanup: deletar
setup/run_estante_pipeline.sheblender/add_estante_anchors.pylegados (mantidos por enquanto pra histórico de troubleshooting) - Adicionar workflow
casco_hogwarts.py(paredes/teto/vitrais via Hunyuan3D) - Avaliar TripoSR como fallback offline (M4 Max via MPS)
- Documentar prompts vencedores em
prompts/