generate_asset: --baker vertex — IDW voxel-grid vertex-color baker (dark-patch fix)
Same sampler as trellis-mac TRELLIS2_BAKER=vertex; Metal texel path retained as-is. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
754d403e62
commit
746e727da2
@ -212,6 +212,40 @@ def _export_pbr(mesh, path: Path, *, baker: str, target: Optional[int], texture_
|
|||||||
faces = torch.from_numpy(simplified_faces).to(dtype=mesh.faces.dtype)
|
faces = torch.from_numpy(simplified_faces).to(dtype=mesh.faces.dtype)
|
||||||
pre_simplified = True
|
pre_simplified = True
|
||||||
|
|
||||||
|
if baker == "vertex":
|
||||||
|
# Dark-patch fix (MODELBEAST BENCHMARKS 2026-07-19): the Metal texel
|
||||||
|
# sampler mangles clean decoder attrs; sample the voxel grid at mesh
|
||||||
|
# vertices (cKDTree IDW, ~0.3s) and ship linear vertex colors.
|
||||||
|
import numpy as np
|
||||||
|
import trimesh
|
||||||
|
from scipy.spatial import cKDTree
|
||||||
|
|
||||||
|
v_np = vertices.numpy()
|
||||||
|
f_np = faces.numpy()
|
||||||
|
coords_np = mesh.coords.cpu().numpy().astype(np.float32)
|
||||||
|
if coords_np.shape[1] == 4:
|
||||||
|
coords_np = coords_np[:, 1:4]
|
||||||
|
attrs_np = mesh.attrs.float().cpu().numpy()
|
||||||
|
vsz = float(mesh.voxel_size)
|
||||||
|
origin = np.array([-0.5, -0.5, -0.5], np.float32)
|
||||||
|
tree = cKDTree(coords_np * vsz + origin + vsz * 0.5)
|
||||||
|
d, idx = tree.query(v_np, k=4, workers=-1)
|
||||||
|
w = 1.0 / (d + vsz * 0.05) ** 2
|
||||||
|
w[d > vsz * 1.5] = 0.0
|
||||||
|
ws = w.sum(1, keepdims=True)
|
||||||
|
has = (ws > 0).squeeze()
|
||||||
|
ws[ws == 0] = 1.0
|
||||||
|
rgb = np.clip(((attrs_np[idx] * (w / ws)[..., None]).sum(1))[:, 0:3], 0, 1)
|
||||||
|
rgb[~has] = np.clip(attrs_np[idx[~has, 0], 0:3], 0, 1)
|
||||||
|
v_gltf = np.stack([v_np[:, 0], v_np[:, 2], -v_np[:, 1]], axis=1)
|
||||||
|
out = trimesh.Trimesh(vertices=v_gltf, faces=f_np, process=False)
|
||||||
|
rgba = np.concatenate([rgb, np.ones((len(v_gltf), 1))], 1)
|
||||||
|
out.visual = trimesh.visual.ColorVisuals(
|
||||||
|
out, vertex_colors=(rgba * 255).astype(np.uint8)) # LINEAR
|
||||||
|
out.export(str(path))
|
||||||
|
return {"baker": "vertex", "pre_simplified": pre_simplified,
|
||||||
|
"triangles": int(len(f_np)), "vertices": int(len(v_np))}
|
||||||
|
|
||||||
if baker == "metal":
|
if baker == "metal":
|
||||||
available, reason = _metal_baker_available()
|
available, reason = _metal_baker_available()
|
||||||
if not available:
|
if not available:
|
||||||
@ -394,7 +428,7 @@ def _parse_args():
|
|||||||
parser.add_argument("image", type=Path)
|
parser.add_argument("image", type=Path)
|
||||||
parser.add_argument("--output-dir", type=Path, required=True)
|
parser.add_argument("--output-dir", type=Path, required=True)
|
||||||
parser.add_argument("--backend", choices=("auto", "mps", "mlx-experimental"), default="auto")
|
parser.add_argument("--backend", choices=("auto", "mps", "mlx-experimental"), default="auto")
|
||||||
parser.add_argument("--baker", choices=("auto", "metal", "kdtree"), default="auto")
|
parser.add_argument("--baker", choices=("auto", "metal", "kdtree", "vertex"), default="auto")
|
||||||
parser.add_argument("--pipeline-type", choices=("512", "1024", "1024_cascade"), default="512")
|
parser.add_argument("--pipeline-type", choices=("512", "1024", "1024_cascade"), default="512")
|
||||||
parser.add_argument("--seed", type=int, default=42)
|
parser.add_argument("--seed", type=int, default=42)
|
||||||
parser.add_argument("--steps", type=int)
|
parser.add_argument("--steps", type=int)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user