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:
parent
a095f1a140
commit
ac817a9a05
@ -2,7 +2,7 @@
|
|||||||
"id": "trellis2_mlx",
|
"id": "trellis2_mlx",
|
||||||
"name": "TRELLIS.2 MLX (local, fastest)",
|
"name": "TRELLIS.2 MLX (local, fastest)",
|
||||||
"category": "mesh-gen",
|
"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"],
|
"accepts": ["image"],
|
||||||
"produces": ["model"],
|
"produces": ["model"],
|
||||||
"resources": "gpu",
|
"resources": "gpu",
|
||||||
@ -14,7 +14,10 @@
|
|||||||
"pipeline_type": {"type": "string", "enum": ["512", "1024", "1024_cascade"], "default": "1024_cascade", "description": "Resolution tier"},
|
"pipeline_type": {"type": "string", "enum": ["512", "1024", "1024_cascade"], "default": "1024_cascade", "description": "Resolution tier"},
|
||||||
"seed": {"type": "integer", "default": 0, "description": "Random seed"},
|
"seed": {"type": "integer", "default": 0, "description": "Random seed"},
|
||||||
"steps": {"type": "integer", "default": 12, "description": "Sampler steps per stage (12 = upstream default)"},
|
"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"}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,15 +36,27 @@ if not py.exists():
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
outdir = Path(a.outdir)
|
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 = [
|
cmd = [
|
||||||
str(py), str(FORK / "scripts" / "generate_asset.py"),
|
str(py), str(FORK / "scripts" / "generate_asset.py"),
|
||||||
str(Path(a.input[0]).resolve()),
|
str(Path(a.input[0]).resolve()),
|
||||||
"--output-dir", str(outdir.resolve()),
|
"--output-dir", str(outdir.resolve()),
|
||||||
"--backend", "mlx-experimental",
|
"--backend", "mlx-experimental",
|
||||||
"--baker", str(p.get("baker", "vertex")),
|
"--baker", str(p.get("baker", "metal")),
|
||||||
"--pipeline-type", str(p.get("pipeline_type", "1024_cascade")),
|
"--pipeline-type", str(p.get("pipeline_type", "1024_cascade")),
|
||||||
"--seed", str(p.get("seed", 0)),
|
"--seed", str(p.get("seed", 0)),
|
||||||
"--texture-size", "2048",
|
"--texture-size", str(p.get("texture_size", 2048)),
|
||||||
|
"--pbr-decimation-target", str(faces),
|
||||||
"--force",
|
"--force",
|
||||||
]
|
]
|
||||||
if p.get("steps"):
|
if p.get("steps"):
|
||||||
@ -52,6 +64,10 @@ if p.get("steps"):
|
|||||||
|
|
||||||
env = os.environ.copy()
|
env = os.environ.copy()
|
||||||
env["HF_HUB_DISABLE_XET"] = "1"
|
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)
|
print("+", " ".join(cmd), flush=True)
|
||||||
res = subprocess.run(cmd, cwd=str(FORK), stdout=sys.stdout,
|
res = subprocess.run(cmd, cwd=str(FORK), stdout=sys.stdout,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user