Support for `KHR_materials_variants`
- Dominant language
- JavaScript
- Stars
- 15.7k
- Forks
- 3.9k
- Avg merge
- 4d 6h
- Merged PRs (30d)
- 34
Description
**tl;dr**:
[KHR_materials_variants](https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_materials_variants/README.md) is a ratified glTF extension that allows defining different material variants for meshes. The extension defines a set of 'variant names' that can be activated. For each mesh primitive, the extension defines the _material_ that should be used when a certain variant is activated.

It should be possible to extract the information about material variants from a glTF asset, and select the active material variant in CesiumJS, switching the material/textures at runtime.
---
Related:
- An older issue that describes the goal of dynamically changing textures: https://github.com/CesiumGS/cesium/issues/5094
This already summarizes some _possible_ approaches, and has some references to the `KHR_materials_variants` extension. Some of the discussion there is a bit out-dated, though (as it refers to older versions and implementations), and was not targeted at explicitly supporting `KHR_materials_variants`
- A recent issue in `cesium-native`: https://github.com/CesiumGS/cesium-native/issues/676
This referred to support of `KHR_materials_variants` in `cesium-native` on the level of the glTF files, **and** on the level of tilesets (more on that below).
---
The first step would be to transport the information about the `KHR_materials_variants` extension through the `Model.fromGltf` loading process. This may already raise some tricky low-level questions (e.g. whether the textures should be loaded immediately, or only when a certain material variant is activated), but should be doable
Based on that, one could expose the information about the material variants on an API level. Clients should be able to do basic things like
```
const materialVariantNames = model.getMaterialVariantNames();
model.setActiveMaterialVariant(materialVariantNames[i]);
```
in a sandcastle. (Eventually, there might even be a UI for that)
---
Support for material variants on a tileset level:
The [issue in `cesium-native`](https://github.com/CesiumGS/cesium-native/issues/676) describes a concept for storing material variants information on the level of a tileset. The summary is:
- The tileset JSON contains metadata that includes an array of strings with the `TILESET_MATERIALS_VARIANTS_NAMES` semantic
- These strings are the material variant names that are expected to be present in *all* glTF assets that are used as the tile content in this tileset
- Setting a certain "active" material variant on the level of the tileset will activate this variant in *all* glTF tile contents that are currently loaded for that tileset
Contributor guide
Research direction
Start by tracing the Model.fromGltf loading process, then read the related issues 5094 and cesium-native 676 for prior approaches and the tileset-level scope. Done would mean transporting KHR_materials_variants data and exposing the proposed material-variant selection API; tileset support is an additional scope described in the issue.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- computer-graphics, frontend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100