Skip to content
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

EXT_mesh_gpu_instancing: Allow quantized quaternions #1820

Merged
merged 3 commits into from
Aug 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 29 additions & 11 deletions extensions/2.0/Vendor/EXT_mesh_gpu_instancing/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@

* John Cooke, OTOY, <mailto:[email protected]>
* Don McCurdy
* Arseny Kapoulkine

## Acknowledgments
* Arseny Kapoulkine, [@zeuxcg](https://twitter.com/zeuxcg)

## Status

Expand All @@ -20,13 +18,13 @@ Written against the glTF 2.0 spec.

This extension is specfically designed to enable GPU instancing which renders many copies of a single mesh at once using a small number of draw calls. It's useful for things
like trees, grass, road signs, etc. The TRANSLATION, ROTATION, and SCALE attributes allows the mesh to be displayed at many different locations with different rotations and scales.
Custom attributes can use the underscore mechanism to achieve other effects (i.e. _ID, _TRANSFORM4x3, etc.).
Custom attributes can use the underscore mechanism to achieve other effects (i.e. _ID, _COLOR, etc.).

## Extending Nodes with per instance attributes
## Extending Nodes With Instance Attributes

Instancing is defined by adding the `EXT_mesh_gpu_instancing` extension to any glTF node that has a mesh. Instancing only applies to mesh nodes, there is no defined behavior for a node
with this extension that doesn't also have a mesh. Applying to nodes rather than meshes allows the same mesh to be used by several nodes, instanced or otherwise. The attributes
section contains accessor ids for the TRANSLATION, ROTATION, and SCALE attribute buffers, all of which are optional. The attributes specify an object space transform that should be
Instancing is defined by adding the `EXT_mesh_gpu_instancing` extension to any glTF node that has a mesh. Instancing only applies to mesh nodes, there is no defined behavior for a node
with this extension that doesn't also have a mesh. Applying to nodes rather than meshes allows the same mesh to be used by several nodes, instanced or otherwise. The attributes
section contains accessor ids for the TRANSLATION, ROTATION, and SCALE attribute buffers, all of which are optional. The attributes specify an object space transform that should be
multipled by the node's world transform in the shader to produce the final world transform for the instance. For example, the following defines some instancing attributes to a node with mesh.

```json
Expand All @@ -50,10 +48,30 @@ multipled by the node's world transform in the shader to produce the final world
}
```

## Appendix
Valid accessor type and component type for each attribute semantic property are defined below.

|Name|Accessor Type|Component Type(s)|Description|
|----|----------------|-----------------|-----------|
|`"TRANSLATION"`|`"VEC3"`|`5126`&nbsp;(FLOAT)|XYZ translation vector|
|`"ROTATION"`|`"VEC4"`|`5126`&nbsp;(FLOAT)<br>`5120`&nbsp;(BYTE)&nbsp;normalized<br>`5122`&nbsp;(SHORT)&nbsp;normalized|XYZW rotation quaternion|
|`"SCALE"`|`"VEC3"`|`5126`&nbsp;(FLOAT)|XYZ scale vector|

All attribute accessors in a given node **must** have the same `count`.

> **Implementation Note:** When instancing is used on the node, the non-instanced version of the mesh should not be rendered.

## Transformation Order

When using instancing, the instance transform matrix is constructed by multiplying translation (if present), rotation (if present), and scale in the same order as they are for nodes:

## Reference
InstanceXform = Translation * Rotation * Scale

The node's world transform matrix is constructed by multiplying the node's local transform matrix from the root of the tree up until (and including) the node itself:

NodeWorldXform = RootXform * ... * ParentLocalXform * NodeLocalXform

The resulting transforms are applied to mesh positions/normals/etc., with instance transformation applied first:

### Theory, Documentation and Implementations
WorldPosition = NodeWorldXform * InstanceXform * VertexPosition

> Note: the construction above assumes column vectors; for row vectors, the matrix multiplication order should be reversed
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"properties": {
"attributes": {
"type": "object",
"description": "A dictionary object, where each key corresponds to mesh attribute semantic and each value is the index of the accessor containing attribute's data (defined optional attribs are TRANSLATION, ROTATION, SCALE. For \"translation\" the values are FLOAT_VEC3's specifying translation along the x, y, and z axes. For \"rotation\" the values are quaternion FLOAT_VEC4's in the order (x, y, z, w), where w is the scalar. For \"scale\" the values are FLOAT_VEC3's specifying scaling factors along the x, y, and z axes.)",
"description": "A dictionary object, where each key corresponds to instance attribute and each value is the index of the accessor containing attribute's data. Attributes TRANSLATION, ROTATION, SCALE define instance transformation. For \"TRANSLATION\" the values are FLOAT_VEC3's specifying translation along the x, y, and z axes. For \"ROTATION\" the values are VEC4's specifying rotation as a quaternion in the order (x, y, z, w), where w is the scalar, with component type `FLOAT` or normalized integer. For \"SCALE\" the values are FLOAT_VEC3's specifying scaling factors along the x, y, and z axes.",
"minProperties": 1,
"additionalProperties": {
"$ref": "glTFid.schema.json"
Expand Down