Skip to content

feat(gltf): native material variants, GPU instancing, visibility, and typed animation - #2987

Merged
ibgreen-openai merged 6 commits into
masterfrom
codex/gltf-native-extensions
Aug 6, 2026
Merged

feat(gltf): native material variants, GPU instancing, visibility, and typed animation#2987
ibgreen-openai merged 6 commits into
masterfrom
codex/gltf-native-extensions

Conversation

@ibgreen-openai

@ibgreen-openai ibgreen-openai commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

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

  • Add GLTFMaterialVariants on scenegraphs.variants, with authored variant names, atomic selectVariant(name), resetVariant(), stable primitive/model identities, and source-derived blend/depth/culling transitions.
  • Execute EXT_mesh_gpu_instancing as one actual instanced WebGL/WebGPU draw per source primitive; decode normalized TRS accessors, preserve application-specific _NAME semantics, expose getGLTFNodeInstancing, and include every placement in aggregate bounds.
  • Implement ratified KHR_node_visibility recursively for renderable scenegraph descendants and punctual lights while preserving complete structural traversal for animation and skinning.
  • Expand KHR_animation_pointer with boolean STEP visibility, independent perspective/orthographic camera projection properties, typed punctual-light color/components, intensity, range, and spotlight angles, and physically implemented KHR_materials_dispersion.dispersion channels.
  • Preserve source camera/light definitions and exported light-array identity while animating runtime copies.
  • Report required extensions through getUnsupportedRequiredGLTFExtensions, assertSupportedGLTFExtensions, and strictExtensions, including a regression proving that required physically implemented dispersion is accepted.
  • Add three small, pinned, attributed CC0 Khronos fixtures: SimpleInstancing, CubeVisibility, and LightVisibility.
  • Keep ANARI as a thin adapter: unsupported glTF camera/light/visibility targets are safely ignored without adding a loader, renderer, material system, or second animation implementation.
  • Restore required SPDX/RAPIDS provenance headers on two graph-degree sources introduced concurrently on master, preserving the repository-wide attribution invariant.

Documentation

  • Add a 452-line native glTF extensions guide at /docs/api-reference/gltf/gltf-native-extensions, with:
    • Complete glTF loading and explicit postProcessGLTF() setup.
    • Authored material-variant JSON, selection/reset examples, stable object identity, and shader-layout limitations.
    • Real WebGL/WebGPU mesh instancing, normalized accessors, local matrices, custom semantics, draw counts, and aggregate bounds.
    • Recursive mesh/light visibility, structural versus visible traversal, and animated boolean STEP pointers.
    • A complete typed node/material/UV/camera/light/dispersion pointer matrix with source-accurate public API examples.
    • Required-extension diagnostics, support-level semantics, source skin palettes, animation timing, crossfades, ownership boundaries, official fixture coverage, and explicit unsupported cases.
  • Expand the glTF animation guide with clip selection/crossfades, delta-vs-wall-clock timing, typed camera/light/visibility/dispersion channels, and automatic source skin palettes for both the standalone glTF and optional retained ANARI paths.
  • Expand the extension support matrix with documented runtime walkthroughs, strict capability diagnostics, animated chromatic dispersion, and truthful rendering-path differences.
  • Add a discoverable Native Extensions documentation tab and sidebar entry while preserving conflict-free integration with the independent interchange documentation PR.

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 current master.
  • 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.ts106 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.ts65 attribution, standards-identity, native-extension, and graph-degree tests pass against current master.
  • node_modules/.bin/vitest run --config /private/tmp/luma-gltf-native-browser-vitest.config.mjs19 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 build from website/, followed by node ./scripts/normalize-llm-output.mjs and node ./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.
  • Scoped Biome source/test checks, formatted navigation, JSON/MDX validation, git diff --check, and exporter-branch three-way merge audits — pass.
  • Standard yarn build, yarn test, yarn lint fix, yarn website:build, and (cd website && yarn build) depend on a stale locally installed @vis.gl/dev-tools wrapper; equivalent strict reference builds, broad node/browser integration, direct production Docusaurus build, and isolated Biome checks were run instead. nvm use and yarn install were unnecessary because existing workspace dependencies were reused.

Architecture / Ownership

  • @luma.gl/engine owns only generic recursive scenegraph visibility, structural traversal, instancing, and shared animation primitives.
  • @luma.gl/gltf owns format-specific extension interpretation, source material variants, source instancing, capability reporting, automatic source skin bindings, and typed scene animation.
  • Existing Material, Model, GroupNode, ModelNode, AnimationMixer, canonical PBR/skin shaders, and loaders.gl decoding remain the sole generic implementations.
  • @luma.gl/anari remains orchestration-only, with isolated optional @luma.gl/anari/gltf integration and no source-specific shading or loading subsystem.
  • This is an independently reviewable direct-to-master draft, refreshed with current merged animation and physical-material foundations; it does not require a stacked PR or reverse engine → glTF dependency.

@ibgreen-openai
ibgreen-openai marked this pull request as ready for review August 6, 2026 13:32
@ibgreen-openai
ibgreen-openai merged commit a547ffd into master Aug 6, 2026
8 checks passed
@ibgreen-openai
ibgreen-openai deleted the codex/gltf-native-extensions branch August 6, 2026 13:32

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment on lines +200 to +202
return Array.from(getGLTFExtensionSupport(gltf).values()).filter(
extension => extension.required && !extension.supported
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

Comment on lines 143 to 145
const mesh =
hasMorphTargets && assignedMorphMeshes.has(sourceMesh.id)
instancing || (hasMorphTargets && assignedMorphMeshes.has(sourceMesh.id))
? createNodeForGLTFMesh(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

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.

2 participants