CesiumGS / CesiumGS/cesium

Support for `KHR_materials_variants`

Open
#11,631 0 comments 1 reaction 0 assignees View on GitHub
category - model/gltf type - enhancement
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.

![Cesium MaterialVariants Demo](https://github.com/CesiumGS/cesium/assets/5597569/34cdc941-d275-449e-b56f-82bf2f7e195d)

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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.