KhronosGroup / KhronosGroup/glTF

Enabling geometry variants in glTF

Open
#2,005 3 comments 2 reactions 0 assignees View on GitHub
Dominant language
HTML
Stars
7.8k
Forks
1.2k
Avg merge
17h 26m
Merged PRs (30d)
5

Description

When using glTF models in a simulation or even on a e-commerce website, it may be useful to provide geometric variations inside a model. The [KHR_materials_variants](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_variants/README.md) extension enables using variants in materials; this issue is for discussion on how to enable node/mesh variants in glTF.

The example I'm working with is of a car (and its components) that can have "damage states". These damage states may be:

```c++
enum DamageState {
Pristine = 0,
Damaged = 1,
Destroyed = 2
}
```

Let's look at what could actually change between damage states, in increasing order of flexibility:

1. A mesh is morphed
- This could be achieved by `KHR_material_variants` and morph targets/animation/skinning (essentially pre-baking static poses).
- This approach requires the least additions to glTF, but it could be really tricky to work with when generating data.
2. A mesh is switched
- This could be achieved by an extension that enables `variants` of a `mesh` in a `node`.
- This approach allows using completely different geometry but the node graph remains unchanged.
3. A node is switched
- This could be achieved by an extension that enables `variants` of a `node`.
- This could get tricky if we want to enable switching node "deeper" in the scene graph, but if all the glTF extension does is provide the variant mappings, it may be feasible to represent something like this:

![Flexible nodes](https://user-images.githubusercontent.com/5172619/125960289-d481c1a7-a666-45b1-a5ce-959dc4a8382b.jpg)

Here's a snippet of a glTF where we use "switch nodes" with variants - using a simple extension inspired by `KHR_material_variants`. A "switch node" cannot have a `mesh` and its children can only be other switch nodes. When a variant is not selected, the `0`th variant is the default.

```json
{
"extensions": {
"EXT_node_variants": {
"variants": [
{ "name": "Pristine" },
{ "name": "Damaged" },
{ "name": "Destroyed" }
]
}
},
"nodes": [
{
"name": "Car Body Switch Node",
"children": [ 4 ],
"extensions": {
"EXT_node_variants": {
"mappings": [
{
"node": 1,
"variants": [0]
},
{
"node": 2,
"variants": [1]
},
{
"node": 3,
"variants": [2]
}
]
}
}
},
{
"name": "Car Body Pristine Node",
"mesh": 0
},
{
"name": "Car Body Damaged Node",
"mesh": 1
},
{
"name": "Car Body Pristine Node",
"mesh": 2
},
{
"name": "Car Door Switch Node",
"children": [ 8 ],
"extensions": {
"EXT_node_variants": {
"mappings": [
{
"node": 5,
"variants": [0]
},
{
"node": 6,
"variants": [1]
},
{
"node": 7,
"variants": [2]
}
]
}
}
},
{
"name": "Car Door Pristine Node",
"mesh": 3
},
{
"name": "Car Door Damaged Node",
"mesh": 4
},
{
"name": "Car Door Destroyed Node",
"mesh": 5
},
{
"name": "Car Door Handle Node",
"extensions": {
"EXT_node_variants": {
"mappings": [
{
"node": 9,
"variants": [0]
},
{
"node": 10,
"variants": [1, 2]
}
]
}
}
},
{
"name": "Car Door Handle Pristine Node",
"mesh": 6
},
{
"name": "Car Door Handle Damaged/Destroyed Node",
"mesh": 7
}
]
}

```

Here is a graphic for the schema above:

![glTF structure](https://user-images.githubusercontent.com/5172619/125960717-2c8b2dd8-5325-4679-bf30-129794e0e14f.jpg)

This is just an initial design and example. We're hoping to get some more insight on how to best achieve the functionality described. Also, discussions on other use cases for such functionality are welcome.

Contributor guide

Open the contributing guide

Research direction

Start with the linked KHR_materials_variants extension README and compare its approach with the proposed EXT_node_variants JSON examples. The issue has no implementation file or test entry point; done would require an agreed design for node or mesh variants and a documented extension direction.

Written by the indexing model from the issue text.

Assessment

Domain
computer-graphics
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.