Skip to content

fix(viewer): preserve GLTF materials in ItemRenderer#246

Open
b9llach wants to merge 1 commit intopascalorg:mainfrom
b9llach:fix/item-renderer-materials-autofit
Open

fix(viewer): preserve GLTF materials in ItemRenderer#246
b9llach wants to merge 1 commit intopascalorg:mainfrom
b9llach:fix/item-renderer-materials-autofit

Conversation

@b9llach
Copy link
Copy Markdown
Contributor

@b9llach b9llach commented Apr 16, 2026

Problem

`getMaterialForOriginal` in `ItemRenderer` returns `baseMaterial` (`#f2f0ed`, roughness 0.5) for every mesh regardless of its source material. The GLTF's original colors, textures, PBR properties, and per-mesh material variation are all thrown away — every loaded model renders as a uniform cream-coloured shape with no visual distinction between parts.

The intent was to convert regular `MeshStandardMaterial` (from GLTFLoader) to `MeshStandardNodeMaterial` (required by the WebGPU/TSL pipeline). The implementation just returned a shared constant instead of actually converting the material's properties.

Fix

Rewrites `getMaterialForOriginal` to build a real `MeshStandardNodeMaterial` from each original material, copying:

  • `color`, `roughness`, `metalness`, `emissive`, `emissiveIntensity`
  • `opacity`, `transparent`, `alphaTest`, `side`, `vertexColors`
  • All texture maps: `map`, `normalMap`, `roughnessMap`, `metalnessMap`, `emissiveMap`, `aoMap`, `alphaMap`

Properties are assigned explicitly after construction rather than passed through the constructor — `Material.setValues` silently drops certain fields on NodeMaterial subclasses (observed: `color` being ignored, producing white output for GLTFs whose material relies solely on `baseColorFactor` like Kenney's low-poly kits).

Results are cached per original material via `WeakMap`. A double-conversion guard detects materials that have already been replaced with a NodeMaterial on a previous render and returns them as-is.

Scope

  • One file: `packages/viewer/src/components/renderers/item/item-renderer.tsx`
  • 44 insertions, 3 deletions — the old `getMaterialForOriginal` (2 lines) is replaced with a proper converter (~40 lines)
  • No schema changes, no store changes, no new dependencies
  • Glass special-case preserved: materials named `glass` still get the shared `glassMaterial`

How to test

  1. `bun dev`, load any scene with `ItemNode`s that reference real GLTF models.
  2. Items should render with their GLTF's actual colors and textures — wood grain on a cabinet, fabric on a chair, metal on a desk. On `main`, every item renders as cream `#f2f0ed`.
  3. Items with glass materials should still render translucent.
  4. `bun check`, `bun check-types`, `bun run build` all clean.

Checklist

  • I've tested this locally with `bun dev`
  • My code follows the existing code style (`bun check` passes on the touched file)
  • I've updated relevant documentation (N/A — no docs affected)
  • This PR targets the `main` branch

`getMaterialForOriginal` returns `baseMaterial` (`#f2f0ed`, roughness
0.5) for every mesh regardless of its source material. The GLTF's
original colors, textures, PBR properties, and per-mesh material
variation are all thrown away. Every loaded model renders as a
uniform cream-coloured shape.

The intent was to convert `MeshStandardMaterial` (from GLTFLoader) to
`MeshStandardNodeMaterial` (required by the WebGPU/TSL pipeline). The
implementation returned a shared constant instead of converting.

This rewrites the converter to build a real `MeshStandardNodeMaterial`
from each original material, copying base color, roughness, metalness,
emissive properties, opacity, side, vertex colors, and all texture
maps. Properties are assigned explicitly after construction rather
than passed through the constructor — `Material.setValues` silently
drops certain fields on NodeMaterial subclasses (observed: `color`
being ignored, producing white output for GLTFs whose material relies
solely on `baseColorFactor`).

Results are cached per original material via `WeakMap`. A double-
conversion guard detects materials already replaced on a previous
render and returns them as-is.
@b9llach b9llach force-pushed the fix/item-renderer-materials-autofit branch from b8b1be8 to f4676cb Compare April 16, 2026 06:24
@b9llach b9llach changed the title fix(viewer): preserve GLTF materials + auto-fit models to scanned dimensions fix(viewer): preserve GLTF materials in ItemRenderer Apr 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant