feat(gltf): native material variants, GPU instancing, visibility, and typed animation - #2987
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b6bdfed5d4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| return Array.from(getGLTFExtensionSupport(gltf).values()).filter( | ||
| extension => extension.required && !extension.supported | ||
| ); |
There was a problem hiding this comment.
Validate required extensions against the features actually used
When a document declares a partially supported extension such as KHR_animation_pointer as required, this filter accepts it solely because the registry labels the extension parsed-and-wired. The parser still deliberately skips unsupported targets such as structural material properties, so {strictExtensions: true} can silently discard a required animation instead of rejecting the asset. Required-extension validation needs to account for unsupported constructs present in the document, not just the extension-level registry flag.
Useful? React with 👍 / 👎.
| const mesh = | ||
| hasMorphTargets && assignedMorphMeshes.has(sourceMesh.id) | ||
| instancing || (hasMorphTargets && assignedMorphMeshes.has(sourceMesh.id)) | ||
| ? createNodeForGLTFMesh( |
There was a problem hiding this comment.
Avoid constructing an unused non-instanced mesh
When a mesh is referenced only by nodes using EXT_mesh_gpu_instancing, the eager pass above has already created a regular model for gltfMeshIdToNodeMap, but this branch always creates a second instanced model and never attaches the regular one to a scene. Destroying the returned scenes therefore cannot reach that first model or its GPU geometry, leaking one complete non-instanced model per such source mesh on every load.
Useful? React with 👍 / 👎.
Goals
Make glTF material variants, mesh instancing, hierarchical visibility, typed scene animation, and extension capability reporting first-class, standards-native runtime features. Provide application-ready documentation that explains exactly how these features work, how they compose with automatic skinning and physical materials, and where the current boundaries remain.
Changes
GLTFMaterialVariantsonscenegraphs.variants, with authored variant names, atomicselectVariant(name),resetVariant(), stable primitive/model identities, and source-derived blend/depth/culling transitions.EXT_mesh_gpu_instancingas one actual instanced WebGL/WebGPU draw per source primitive; decode normalized TRS accessors, preserve application-specific_NAMEsemantics, exposegetGLTFNodeInstancing, and include every placement in aggregate bounds.KHR_node_visibilityrecursively for renderable scenegraph descendants and punctual lights while preserving complete structural traversal for animation and skinning.KHR_animation_pointerwith booleanSTEPvisibility, independent perspective/orthographic camera projection properties, typed punctual-light color/components, intensity, range, and spotlight angles, and physically implementedKHR_materials_dispersion.dispersionchannels.getUnsupportedRequiredGLTFExtensions,assertSupportedGLTFExtensions, andstrictExtensions, including a regression proving that required physically implemented dispersion is accepted.SimpleInstancing,CubeVisibility, andLightVisibility.master, preserving the repository-wide attribution invariant.Documentation
/docs/api-reference/gltf/gltf-native-extensions, with:postProcessGLTF()setup.STEPpointers.Verification
node_modules/.bin/tspc -b modules/anari/tsconfig.json --force— pass; strictly compiles the complete ANARI → glTF → engine/core/shadertools project-reference graph after merging currentmaster.node_modules/.bin/tsc --project /private/tmp/luma-gltf-native-docs-contract.json --noEmit --pretty false— pass; strictly type-checks every documented public variants/instancing/visibility/pointer/animation/skin/capability API against actual workspace source.node /private/tmp/luma-gltf-native-docs-audit.mjs— pass; validates all three MDX pages, 20 TypeScript examples, 4 JSON examples, 12 local documentation routes, sidebar/tab registration, and conflict-free three-way merges with the separate interchange PR.node_modules/.bin/vitest run --config /private/tmp/luma-anari-vitest.config.mjs modules/gltf/test modules/anari/test modules/engine/test/scenegraph modules/engine/test/animation/skin.node.spec.ts— 106 tests across 21 suites pass, covering official extension fixtures, strict required dispersion, existing skin/morph/material behavior, and retained ANARI integration.node_modules/.bin/vitest run --config /private/tmp/luma-anari-vitest.config.mjs test/examples/rapids-attribution.node.spec.ts test/examples/standards-identity.node.spec.ts modules/gltf/test/gltf/gltf-native-extensions.node.spec.ts modules/experimental/test/lugraph/lu-graph-degree.node.spec.ts— 65 attribution, standards-identity, native-extension, and graph-degree tests pass against currentmaster.node_modules/.bin/vitest run --config /private/tmp/luma-gltf-native-browser-vitest.config.mjs— 19 real Chromium WebGL/WebGPU tests across 3 suites pass, including an actual instanced draw from the official Khronos fixture./Users/ib/opensource/luma.gl/node_modules/.bin/docusaurus buildfromwebsite/, followed bynode ./scripts/normalize-llm-output.mjsandnode ./scripts/check-llm-output.mjs— full production website plus 472 indexed raw documentation pages pass; the new guide renders as both HTML and indexed raw Markdown.git diff --check, and exporter-branch three-way merge audits — pass.yarn build,yarn test,yarn lint fix,yarn website:build, and(cd website && yarn build)depend on a stale locally installed@vis.gl/dev-toolswrapper; equivalent strict reference builds, broad node/browser integration, direct production Docusaurus build, and isolated Biome checks were run instead.nvm useandyarn installwere unnecessary because existing workspace dependencies were reused.Architecture / Ownership
@luma.gl/engineowns only generic recursive scenegraph visibility, structural traversal, instancing, and shared animation primitives.@luma.gl/gltfowns format-specific extension interpretation, source material variants, source instancing, capability reporting, automatic source skin bindings, and typed scene animation.Material,Model,GroupNode,ModelNode,AnimationMixer, canonical PBR/skin shaders, and loaders.gl decoding remain the sole generic implementations.@luma.gl/anariremains orchestration-only, with isolated optional@luma.gl/anari/gltfintegration and no source-specific shading or loading subsystem.masterdraft, refreshed with current merged animation and physical-material foundations; it does not require a stacked PR or reverse engine → glTF dependency.