feat(trellis2_mlx): metal PBR baker by default — the fast lane now ships meshgod-grade textures

Fork lane (72s vertex) gains the trellis_mac 2026-07-22 quality fixes:
metal UV-PBR bake with explicit RAM-sized face cap (the fork bakes FULL
density when no target passed — 75GB peak; always pass one), forced-
opaque alpha, texture_size/max_bake_faces/alpha_mode params. Verified
m3ultra: 156s e2e, 26.2GB peak, 391,782-tri candidate + 2.19M-tri raw
master. Vendor checkout synced to fork ba4e2ad.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
m3ultra 2026-07-22 19:36:38 +10:00
parent a095f1a140
commit ac817a9a05
2 changed files with 23 additions and 4 deletions

View File

@ -2,7 +2,7 @@
"id": "trellis2_mlx",
"name": "TRELLIS.2 MLX (local, fastest)",
"category": "mesh-gen",
"description": "Image → full-density vertex-baked GLB via the MRP MLX fork of TRELLIS.2 (monster/trellis-2-mrp-mlx): pure-MLX sampler + vertex baker + validated pipeline. 72s/gen @ 26.5GB on m3ultra, 182s @ 17.2GB on m1ultra — 3× faster and 3× lighter than the torch-MPS trellis_mac operator. Vertex-colored output (albedo; no MR maps) — pair with the MESHGOD finish farm for game budgets. Weights: TRELLIS.2-4B + gated DINOv3/RMBG (rsync from m3 HF cache to workers; no HF login needed).",
"description": "Image → PBR GLB via the MRP MLX fork of TRELLIS.2 (monster/trellis-2-mrp-mlx): pure-MLX sampler, Metal PBR bake with RAM-sized face cap + forced-opaque alpha (2026-07-22 quality fixes — fal-parity detail), kdtree/vertex fallbacks. ~72s vertex / ~2min metal-PBR on m3ultra — still the fastest local TRELLIS.2. baker=vertex for the 1s clean-albedo bake (no MR maps). Weights: TRELLIS.2-4B + gated DINOv3/RMBG (rsync from m3 HF cache to workers; no HF login needed).",
"accepts": ["image"],
"produces": ["model"],
"resources": "gpu",
@ -14,7 +14,10 @@
"pipeline_type": {"type": "string", "enum": ["512", "1024", "1024_cascade"], "default": "1024_cascade", "description": "Resolution tier"},
"seed": {"type": "integer", "default": 0, "description": "Random seed"},
"steps": {"type": "integer", "default": 12, "description": "Sampler steps per stage (12 = upstream default)"},
"baker": {"type": "string", "enum": ["vertex", "metal", "kdtree"], "default": "vertex", "description": "vertex = 1s bake, clean colors (recommended); metal = UV textures but has the dark-patch sampling bug"}
"baker": {"type": "string", "enum": ["metal", "vertex", "kdtree"], "default": "metal", "description": "metal = UV PBR textures (meshgod-grade; minor dark-patch texels remain); vertex = 1s bake, cleanest colors, no MR maps"},
"texture_size": {"type": "integer", "enum": [512, 1024, 2048, 4096], "default": 2048, "description": "Baked texture resolution (metal/kdtree bakers)"},
"max_bake_faces": {"type": "integer", "enum": [200000, 500000, 1000000], "default": 500000, "description": "Pre-bake face cap. 500k ≈ fal parity (M3 Ultra verified); node RAM sizes the default when unset — laptops get 200k"},
"alpha_mode": {"type": "string", "enum": ["opaque", "auto"], "default": "opaque", "description": "opaque = force alphaMode OPAQUE (fixes speckle-veil hair); auto = keep baked alpha for glassy subjects"}
}
}
}

View File

@ -36,15 +36,27 @@ if not py.exists():
sys.exit(1)
outdir = Path(a.outdir)
# Meshgod-grade PBR by default (metal baker + capped bake), matching the
# trellis_mac lane's 2026-07-22 quality fixes. The fork's schedule bakes the
# FULL-density mesh when no target is passed (75GB peak, 131MB GLB) — always
# pass an explicit cap; RAM-sized default like trellis_mac (500k ≈ fal parity
# on ≥96GB Studios, 200k mtlbvh-safe elsewhere).
faces = p.get("max_bake_faces")
if faces is None:
mem_gb = os.sysconf("SC_PAGE_SIZE") * os.sysconf("SC_PHYS_PAGES") / 1e9
faces = 500000 if mem_gb >= 96 else 200000
cmd = [
str(py), str(FORK / "scripts" / "generate_asset.py"),
str(Path(a.input[0]).resolve()),
"--output-dir", str(outdir.resolve()),
"--backend", "mlx-experimental",
"--baker", str(p.get("baker", "vertex")),
"--baker", str(p.get("baker", "metal")),
"--pipeline-type", str(p.get("pipeline_type", "1024_cascade")),
"--seed", str(p.get("seed", 0)),
"--texture-size", "2048",
"--texture-size", str(p.get("texture_size", 2048)),
"--pbr-decimation-target", str(faces),
"--force",
]
if p.get("steps"):
@ -52,6 +64,10 @@ if p.get("steps"):
env = os.environ.copy()
env["HF_HUB_DISABLE_XET"] = "1"
# "auto" keeps o_voxel's baked-alpha BLEND detection (glass etc.); default
# opaque — noisy baked alpha renders solid hair as a speckle veil.
if p.get("alpha_mode"):
env["TRELLIS2_ALPHA_MODE"] = str(p["alpha_mode"])
print("+", " ".join(cmd), flush=True)
res = subprocess.run(cmd, cwd=str(FORK), stdout=sys.stdout,