--- license: mit tags: - 3d-generation - hunyuan3d - hunyuan3d-2.1 - sdxl - vastai - unity - vr - quest3 - gltfast language: - pt - en --- # 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) ```bash # SSH no instance (dentro de tmux SEMPRE) tmux new -s paint git clone https://huggingface.co//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) ```bash # 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 ```bash scp -P -i ~/.ssh/ \ root@:/tmp/out/textured_pbr.glb \ ./outputs/.glb # Copia direto pra Unity Assets/ cp ./outputs/.glb \ /Assets/_Project/Models/Furniture/ # Unity importa nativamente via com.unity.cloud.gltfast (já instalado). # AssetDatabase.LoadAssetAtPath(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): ```csharp var go = (GameObject)PrefabUtility.InstantiatePrefab( AssetDatabase.LoadAssetAtPath(glbPath)); var renderers = go.GetComponentsInChildren(); 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().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`](docs/troubleshooting.md). Resumo: 1. **Repo correto**: clone `github.com/Tencent-Hunyuan/Hunyuan3D-2.1` (não o repo `Hunyuan3D-2` antigo). HF `tencent/Hunyuan3D-2.1` é só weights. 2. **`mesh_utils.py`**: lazy `import bpy` + `convert_obj_to_glb` via trimesh (bpy não tem wheel pra Python 3.12). 3. **`simplify_mesh_utils.py`**: `fast_simplification 0.1.13` mudou API `target_count` → `target_reduction`. Patch inline no install. 4. **Compile inpaint**: `cd hy3dpaint/DifferentiableRenderer && bash compile_mesh_painter.sh` 5. **Build custom_rasterizer**: `cd hy3dpaint/custom_rasterizer && pip install --no-build-isolation .` 6. **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). 7. **`setuptools < 81`** (pkg_resources removido em 81+, pytorch-lightning 1.9.5 ainda usa). 8. **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/.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.gltfast` package - (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 `LICENSE` no 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.sh` e `blender/add_estante_anchors.py` legados (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/`