-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Edit pass over the 3D Tiles Next extensions #62
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,11 +17,15 @@ Draft | |
|
||
## Dependencies | ||
|
||
Written against the glTF 2.0 specification. It depends on the [`EXT_mesh_gpu_instancing`](../EXT_mesh_gpu_instancing) extension. Each node that is extended with `EXT_instance_features` must also define an `EXT_mesh_gpu_instancing` extension object, and is invalid without this dependency. | ||
Written against the glTF 2.0 specification. Depends on the [`EXT_mesh_gpu_instancing`](../EXT_mesh_gpu_instancing) extension. Each node that is extended with `EXT_instance_features` must also define an `EXT_mesh_gpu_instancing` extension object, and is invalid without this dependency. | ||
|
||
## Optional vs. Required | ||
|
||
This extension is optional, meaning it should be placed in the `extensionsUsed` list, but not in the `extensionsRequired` list. | ||
|
||
## Overview | ||
|
||
In most realtime 3D contexts, performance requirements demand minimizing the number of nodes and meshes in an asset. These requirements compete with interactivity, as applications may wish to merge static objects while still supporting interaction or inspection on those objects. A common performance optimizations is GPU instancing, using the `EXT_mesh_gpu_instancing` extension. But this does not allow to uniquely identify the instances that are created during rendering. | ||
In most realtime 3D contexts, performance requirements demand minimizing the number of nodes and meshes in an asset. These requirements compete with interactivity, as applications may wish to merge static objects while still supporting interaction or inspection on those objects. A common performance optimizations is GPU instancing, using the `EXT_mesh_gpu_instancing` extension. But this does not allow uniquely identifying the instances that are created during rendering. | ||
|
||
This extension defines a means of associating GPU instances that are created using the `EXT_mesh_gpu_instancing` extension with unique identifiers. These allow identifying the GPU instances as individual _features_, and are therefore referred to as _feature IDs_. These feature IDs are similar to the concept that is introduced in the [`EXT_mesh_features`](../EXT_mesh_features) extension. But instead of defining the feature IDs based on vertex attributes, the feature IDs are here defined using instance attributes. | ||
|
||
|
@@ -31,7 +35,7 @@ This extension defines a means of associating GPU instances that are created usi | |
|
||
Feature IDs may be assigned to individual GPU instances using an instance attribute, or generated implicitly by instance index. | ||
|
||
When the feature ID definition does not refer to an instance attribute, then the feature IDs that are assigned to the instances are equal to their index, in the range [0, count), where `count` is the `count` of the instance attribute accessors. When the feature ID definition refers to an instance attribute, then this attribute contains `count` feature ID values. Note that these values do not necessarily have to be distinct; this makes it possible to define _groups_ of instances that share the same identifier. | ||
When the feature ID definition does not refer to an instance attribute, then the feature IDs that are assigned to the instances are equal to their index, in the range `[0, count)`, where `count` is the `count` of the instance attribute accessors. When the feature ID definition refers to an instance attribute, then this attribute contains `count` feature ID values. Note that these values do not necessarily have to be distinct; this makes it possible to define _groups_ of instances that share the same identifier. | ||
|
||
> **Example:** A node defining instances of mesh `0`, with each instance having a feature ID in the `_FEATURE_ID_0` instance attribute. | ||
> | ||
|
@@ -61,15 +65,57 @@ When the feature ID definition does not refer to an instance attribute, then the | |
> } | ||
> ``` | ||
## Optional vs. Required | ||
A feature ID set may also include the following properties: | ||
This extension is optional, meaning it should be placed in the `extensionsUsed` list, but not in the `extensionsRequired` list. | ||
* `nullFeatureId`: a value that indicates that a certain instance is not considered to be an identifiable object | ||
* `label`: an alphanumeric string used to identify feature ID sets across different glTF nodes | ||
* `propertyTable`: the index of a property table in the [`EXT_structural_metadata`](../EXT_structural_metadata/) extension | ||
> **Example:** A more complex example with two feature ID sets. The first feature ID set groups instanced trees into forests. The tree with feature ID `2` matches the `nullFeatureId` and therefore does not belong to a forest feature. The second feature ID set (feature ID values not shown) is defined implicitly based on instance index, and identifies individual trees. Each feature ID set refers to a property table that contains metadata about the features. | ||
> | ||
>  | ||
> | ||
> ```jsonc | ||
> { | ||
> "nodes": [ | ||
> { | ||
> "mesh": 0, | ||
> "extensions": { | ||
> "EXT_mesh_gpu_instancing": { | ||
> "attributes": { | ||
> "TRANSLATION": 0, | ||
> "ROTATION": 1, | ||
> "SCALE": 2, | ||
> "_FEATURE_ID_0": 3 | ||
> }, | ||
> }, | ||
> "EXT_instance_features": { | ||
> "featureIds": [ | ||
> { | ||
> "nullFeatureId": 2, | ||
> "featureCount": 2, | ||
> "attribute": 0, | ||
> "propertyTable": 0, | ||
> "label": "Forests" | ||
> }, | ||
> { | ||
> "featureCount": 9, | ||
> "propertyTable": 1, | ||
> "label": "Trees" | ||
> } | ||
> ] | ||
> } | ||
> } | ||
> } | ||
> ] | ||
> } | ||
> ``` | ||
Comment on lines
+68
to
+112
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added a second example to show other concepts like grouping instances into features and defining implicit feature IDs |
||
## Schema | ||
* [node.EXT_instance_features.schema.json](./schema/node.EXT_instance_features.schema.json) | ||
## Revision History | ||
This extension was originally part of a the `EXT_mesh_features` proposal extension. The revision history of this extension can be found in the [common revision history of the 3D Tiles Next extensions](https://github.com/CesiumGS/3d-tiles/blob/main/next/REVISION_HISTORY.md). | ||
This extension was originally part of the `EXT_mesh_features` extension. The revision history of this extension can be found in the [common revision history of the 3D Tiles Next extensions](https://github.com/CesiumGS/3d-tiles/blob/main/next/REVISION_HISTORY.md). | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,7 +47,7 @@ The feature ID set may also include a `label`, an alphanumeric string used to id | |
|
||
Feature IDs can be associated with parts of a model in one of three ways: | ||
|
||
* **Feature ID by Vertex:** Feature IDs that are stored as vertex attribute, using a standard glTF accessor. The `featureId.attribute` refers to this accessor, and allows defining feature IDs for each individual vertex. | ||
* **Feature ID by Vertex:** Feature IDs that are stored as a vertex attribute, using a standard glTF accessor. The `featureId.attribute` refers to this accessor, and allows defining feature IDs for each individual vertex. | ||
* **Feature ID by Texture Coordinates:** Feature IDs that are stored in the channels of a standard glTF texture. The `featureId.texture` refers to this texture, and allows defining feature IDs for regions on the surface of a mesh. | ||
* **Feature ID by Index**: Feature IDs that are assigned implicitly to the vertices. In this case, the feature ID is given by the index of the vertex. | ||
|
||
|
@@ -89,8 +89,7 @@ Per-vertex feature IDs can be used to identify individual objects that have been | |
> "EXT_mesh_features": { | ||
> "featureIds": [{ | ||
> "featureCount": 2, | ||
> "attribute": 0, | ||
> "label": "buildings" | ||
> "attribute": 0 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
> }] | ||
> } | ||
> } | ||
|
@@ -105,7 +104,7 @@ Per-vertex feature IDs can be used to identify individual objects that have been | |
|
||
Feature ID textures classify the pixels of an image into different features. Some use cases include image segmentation or marking regions on a map. Often per-texel feature IDs provide finer granularity than per-vertex feature IDs, as in the example below. | ||
|
||
> **Example:** A building facade, represented by a single quad. The primitive's `baseColorTexture` displays the visible appearance of the building, and its feature ID texture identifies regions of the quad (door, roof, window) as distinct features. Texels assigned `nullFeatureId` do not belong to a feature. Both textures use the same texture coordinates, `TEXCOORD_0`, in this example. | ||
> **Example:** A building facade, represented by a single quad. The primitive's `baseColorTexture` displays the visible appearance of the building, and its feature ID texture identifies regions of the quad (door, roof, window) as distinct features. Both textures use the same texture coordinates, `TEXCOORD_0`, in this example. Texels assigned `nullFeatureId` do not belong to a feature. | ||
> | ||
> <img src="figures/feature-id-by-texture.png" alt="Feature ID Texture" width="800"> | ||
> | ||
|
@@ -122,13 +121,13 @@ Feature ID textures classify the pixels of an image into different features. Som | |
> "extensions": { | ||
> "EXT_mesh_features": { | ||
> "featureIds": [{ | ||
> "nullFeatureId": 0, | ||
> "featureCount": 3, | ||
> "texture" : { | ||
> "index": 0, | ||
> "texCoord": 0, | ||
> "channels": [0] | ||
> }, | ||
> "nullFeatureId": 0, | ||
> } | ||
> }] | ||
> } | ||
> } | ||
|
@@ -142,23 +141,23 @@ The `texture` object of a `featureId` extends the glTF [`textureInfo`](../../../ | |
The values from the selected channels are treated as unsigned 8 bit integers, and represent the bytes of the actual feature ID, in little-endian order. | ||
|
||
> **Example:** | ||
> If a `featureID.texture` defines `"channels": [0, 1]`, then the actual feature ID can be computed as `id = channel[0] | (channel[1] << 8);`. | ||
> If a `featureID.texture` defines `"channels": [1, 0, 2]`, then the actual feature ID can be computed as `id = channel[1] | (channel[0] << 8) | (channel[2] << 16);`. | ||
> If a `featureID.texture` defines `"channels": [0, 1]`, then the actual feature ID can be computed as `id = channel[0] | (channel[1] << 8)`. | ||
> If a `featureID.texture` defines `"channels": [1, 0, 2]`, then the actual feature ID can be computed as `id = channel[1] | (channel[0] << 8) | (channel[2] << 16)`. | ||
|
||
Texture filtering must be `9728` (NEAREST), or undefined, for any texture object referenced as a feature ID texture. Texture values must be encoded with a linear transfer function. | ||
|
||
#### Feature ID by Index | ||
|
||
When both `featureId.attribute` and `featureId.texture` are undefined,then the feature ID value for each vertex is given implicitly, via the index of the vertex. In this case, the `featureCount` must match the number of vertices of the mesh primitive. | ||
When both `featureId.attribute` and `featureId.texture` are undefined, then the feature ID value for each vertex is given implicitly, via the index of the vertex. In this case, the `featureCount` must match the number of vertices of the mesh primitive. | ||
|
||
|
||
### Using Feature IDs | ||
|
||
The feature ID sets that are associated with mesh primitives can be accessed by client applications, and be used to look up addition information that is associated with these features. Two possible ways of associating features with additional information are presented here. | ||
The feature ID sets that are associated with mesh primitives can be accessed by client applications, and can be used to look up addition information that is associated with these features. Two possible ways of associating features with additional information are presented here. | ||
|
||
#### Referencing Property Tables with Feature IDs | ||
|
||
When combined with the `EXT_structural_metadata` extension, feature ID sets can be associated with property tables. A property table maps each feature ID to a set of values that are associated with the respective feature. The feature ID in this case serves as an _index_ for the row of the table. The index of the property table that a certain set of feature IDs is associated with is stored in the `propertyTable` of the feature ID set definition. | ||
When combined with the [`EXT_structural_metadata`](../EXT_structural_metadata/) extension, feature ID sets can be associated with property tables. A property table maps each feature ID to a set of values that are associated with the respective feature. The feature ID in this case serves as an _index_ for the row of the table. The index of the property table that a certain set of feature IDs is associated with is stored in the `propertyTable` of the feature ID set definition. | ||
|
||
> **Example:** This example assumes that an array of property tables is defined in the asset, using the `EXT_structural_metadata` extension. The example shows a primitive with multiple feature ID sets. The first one uses a feature ID texture that contains 4 different features. The second one is defined via a vertex attribute, and defines 2 different features. The first ID set is associated with the property table with index 1. The second one is associated with the property table with index 0. | ||
> | ||
|
@@ -174,12 +173,14 @@ When combined with the `EXT_structural_metadata` extension, feature ID sets can | |
> "texCoord": 0, | ||
> "channels": [0] | ||
> }, | ||
> "propertyTable": 1 | ||
> "propertyTable": 1, | ||
> "label": "classification" | ||
> }, | ||
> { | ||
> "featureCount": 2, | ||
> "attribute": 0, | ||
> "propertyTable": 0 | ||
> "propertyTable": 0, | ||
> "label": "components" | ||
Comment on lines
-177
to
+183
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The is a better example to add |
||
> } | ||
> ] | ||
> } | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved the
Optional vs. Required
section sooner in the document