-
Notifications
You must be signed in to change notification settings - Fork 1.2k
EXT_mesh_primitive_restart #2478
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
Merged
Merged
Changes from 9 commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
f23bb98
schema
pmconne c3e009c
README (wip)
pmconne 5b734bb
README
pmconne 14174f3
tweak
pmconne 79d3a4f
Add constraints; remove issue link
pmconne 2d565df
React to feedback
pmconne ecfb4f4
define fall back on constraint violation
pmconne bf3edc9
Adjust language, prohibit morph targets
pmconne 4752dee
Add link to primitiveGroup schema
pmconne 1223e9a
EXT_mesh_primitive_restart
pmconne 79b6919
schema formatting
pmconne 014846c
Fix POSITIONS accessor index
pmconne 9a40bb4
Fix other POSITIONS attribute index
pmconne 708fdb0
rm empty line
pmconne a8ced66
End file with newline
pmconne 624cd65
upgrade JSON schema version
pmconne e217482
Fallback is not required in case of constraint violation
pmconne d44974e
Add known implementation
pmconne 5b24bc3
Remove name
pmconne 4029fd2
/s/Draft/Complete
pmconne 696728d
Remove copyright
pmconne File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
159 changes: 159 additions & 0 deletions
159
extensions/2.0/Vendor/BENTLEY_primitive_restart/README.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,159 @@ | ||
| <!-- | ||
| Copyright 2015-2021 The Khronos Group Inc. | ||
| SPDX-License-Identifier: CC-BY-4.0 | ||
| --> | ||
|
|
||
| # BENTLEY_primitive_restart | ||
|
|
||
| ## Contributors | ||
|
|
||
| * Paul Connelly, Bentley Systems, [@pmconne](https://github.com/pmconne) | ||
|
|
||
| ## Status | ||
|
|
||
| Draft | ||
|
|
||
| ## Dependencies | ||
|
|
||
| Written against the glTF 2.0 spec. | ||
|
|
||
| ## Overview | ||
|
|
||
| "Primitive restart" is a feature of the input assembly stage that restarts the current primitive when the vertex index value is the maximum possible value for a given index buffer type. For example, the line strip primitive usually produces one continuous connected series of line segments, but with primitive restart enabled, a maximal vertex index value (e.g., 65535 for unsigned 16-bit integer indices) indicates the beginning of a new line string disconnected from those preceding it. Primitive restart can be useful for batching multiple line strips, line loops, triangle strips, or triangle fans into a single draw call. Alternatively, batching can be achieved by decomposing the primitives into lines or triangles, but this may introduce many redundant vertices, increasing the amount of data required to describe the geometry. | ||
|
|
||
| glTF 2.0 explicitly prohibits index buffers from containing maximal index values because support for primitive restart varies amongst graphics APIs. Per [section 3.7.2.1](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#meshes-overview) of the spec, | ||
|
|
||
| > `indices` accessor **MUST NOT** contain the maximum possible value for the component type used (i.e., 255 for unsigned bytes, 65535 for unsigned shorts, 4294967295 for unsigned ints). | ||
|
|
||
| This extension permits the above prohibition to be selectively relaxed, while providing a trivial fallback for implementations that don't support primitive restart. | ||
|
|
||
| ## Example | ||
|
|
||
| Consider the simple example of a pair of line strings with a total of 5 vertices where vertices 0 and 1 make up the first line string and vertices 2, 3, and 4 make up the second. An unsigned byte index buffer representing these line strings using primitive restart would look like the following, where index 255 marks the disconnect between the two line strings: | ||
|
|
||
| ``` | ||
| [0, 1, 255, 2, 3, 4] | ||
| ``` | ||
|
|
||
| Over this same buffer, we can alternatively produce 2 separate accessors - one per line string - splitting at (and omitting) the prohibited primitive restart value: | ||
|
|
||
| ``` | ||
| [0, 1, 255, 2, 3, 4] | ||
| [0, 1] [2, 3, 4] | ||
| ``` | ||
|
|
||
| This permits two equivalent representations of the geometry without duplicating any binary data. In glTF, the accessors look like this: | ||
|
|
||
| ```json | ||
| "accessors": [ | ||
| { | ||
| "bufferView": 0, | ||
| "count": 2, | ||
| "componentType": 5121, | ||
| "type": "SCALAR", | ||
| "name": "Line string 1 indices" | ||
| }, | ||
| { | ||
| "bufferView": 0, | ||
| "byteOffset": 3, | ||
| "count": 3, | ||
| "componentType": 5121, | ||
| "type": "SCALAR", | ||
| "name": "Line string 2 indices" | ||
| }, | ||
| { | ||
| "bufferView": 0, | ||
| "componentType": 5121, | ||
| "count": 6, | ||
| "type": "SCALAR", | ||
| "name": "All indices" | ||
| }, | ||
| { | ||
| "bufferView": 1, | ||
| "componentType": 5126, | ||
| "count": 5, | ||
| "type": "VEC3", | ||
| "max": [ | ||
| 0.5, | ||
| 0.5, | ||
| 0.0 | ||
| ], | ||
| "min": [ | ||
| -0.5, | ||
| -0.5, | ||
| 0.0 | ||
| ], | ||
| "name": "Positions accessor" | ||
| } | ||
| ], | ||
|
|
||
| ``` | ||
|
|
||
| The mesh looks like this: | ||
|
|
||
| ```json | ||
| "meshes": [ | ||
| { | ||
| "primitives": [ | ||
| { | ||
| "attributes": { | ||
| "POSITION": 0 | ||
| }, | ||
| "indices": 0, | ||
| "material": 0, | ||
| "mode": 3 | ||
| }, | ||
| { | ||
| "attributes": { | ||
| "POSITION": 0 | ||
| }, | ||
| "indices": 1, | ||
| "material": 0, | ||
| "mode": 3 | ||
| } | ||
| ], | ||
| "extensions": { | ||
| "BENTLEY_primitive_restart": { | ||
| "primitiveGroups": [ | ||
| { | ||
| "primitives": [ | ||
| 0, | ||
| 1 | ||
| ], | ||
| "indices": 2 | ||
| } | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| ], | ||
| ``` | ||
|
|
||
| By default, this mesh draws two separate line strip primitives, each using its own `indices` accessor. The `BENTLEY_primitive_restart` extension specifies that both primitives can be replaced with a single one using a combined `indices` accessor containing primitive restart values. | ||
|
|
||
| ## glTF Schema Updates | ||
|
|
||
| The `BENTLEY_primitive_restart` extension is applied to a mesh. Its `primitiveGroups` property is a list of groups of primitives that can be replaced with a single primitive using primitive restart. Each group is described by a list of indices into `mesh.primitives`, along with the index of the accessor that supplies the vertex indices for the replacement primitive. | ||
|
|
||
| ## Constraints | ||
pmconne marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| The extension is subject to the following constraints. Violation of any constraint renders the entire extension invalid, in which case the extension **MUST** be ignored and the `mesh.primitives` objects are rendered as defined in the glTF 2.0 specification. | ||
|
|
||
| - A given primitive index **MUST NOT** appear in more than one primitive group. | ||
|
|
||
| - Each primitive index in a primitive group **MUST NOT** appear more than once in that group. | ||
|
|
||
| - Each primitive in each group **MUST** use one of the following topology types, as specified by the `mode` property: 2 (line loop), 3 (line strip), 5 (triangle strip), or 6 (triangle fan). No other topology types are permitted. | ||
|
|
||
| - All primitives in a given group **MUST** have identical property values (e.g., attributes, material, mode, etc), with the exception of `indices`. This includes the `extensions` property - e.g., if any primitive in a group has a `KHR_materials_variants` extension object, then all other primitives in the same group **MUST** have that extension with identical content. | ||
|
|
||
lexaknyazev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| - Each primitive in each group **MUST** define an `indices` property, i.e., they **MUST** use indexed geometry. | ||
|
|
||
| - The `indices` accessor specified by each primitive group **MUST** be a valid index accessor as per the base glTF 2.0 specification, i.e., their types **MUST** be scalar, their component types **MUST** be any of the unsigned integer types, and their buffer views (if defined) **MUST NOT** be used for any purpose other than vertex indices. | ||
|
|
||
| - Primitives referred to by this extension **MUST NOT** have morph targets. | ||
|
|
||
| ## JSON Schema | ||
|
|
||
| - [mesh.BENTLEY_primitive_restart.schema.json](schema/mesh.BENTLEY_primitive_restart.schema.json) | ||
| - [primitiveGroup.schema.json](schema/primitiveGroup.schema.json) | ||
27 changes: 27 additions & 0 deletions
27
...ns/2.0/Vendor/BENTLEY_primitive_restart/schema/mesh.BENTLEY_primitive_restart.schema.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| { | ||
| "$schema": "http://json-schema.org/draft-04/schema", | ||
| "$id": "mesh.BENTLEY_primitive_restart", | ||
| "title": "BENTLEY_primitive_restart glTF extension", | ||
| "type": "object", | ||
| "description": "glTF extension enabling the use of primitive restart values in index buffers", | ||
| "allOf": [ | ||
| { | ||
| "$ref": "glTFProperty.schema.json" | ||
| } | ||
| ], | ||
| "properties": { | ||
| "primitiveGroups": { | ||
| "type": "array", | ||
lexaknyazev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| "items": { | ||
| "$ref": "primitiveGroup.schema.json" | ||
| }, | ||
| "minItems": 1, | ||
| "description": "The list of groups of primitives that can be drawn using a single index buffer with primitive restart" | ||
| }, | ||
| "extensions": {}, | ||
| "extras": {} | ||
| }, | ||
| "required": [ | ||
| "primitiveGroups" | ||
| ] | ||
| } | ||
40 changes: 40 additions & 0 deletions
40
extensions/2.0/Vendor/BENTLEY_primitive_restart/schema/primitiveGroup.schema.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| { | ||
| "$schema": "http://json-schema.org/draft-04/schema", | ||
| "$id": "primitiveGroup", | ||
| "title": "Primitive Group", | ||
| "type": "object", | ||
| "description": "A group of primitives that can be drawn together using a single index buffer containing restart values", | ||
| "allOf": [ | ||
| { | ||
| "$ref": "glTFProperty.schema.json" | ||
| } | ||
| ], | ||
| "properties": { | ||
| "primitives": { | ||
| "type": "array", | ||
| "items": { | ||
| "$ref": "glTFid.schema.json" | ||
| }, | ||
| "uniqueItems": true, | ||
| "minItems": 1, | ||
| "description": "The indices of the primitives that will be combined and drawn using a single set of indices", | ||
| "gltf_detailedDescription": "The indices of the primitives that will be combined and drawn using a single set of indices. All properties except for `indices` (e.g., `material`, `mode`, and `attributes`) will be obtained from the first primitive in the list, and all other primitives in the list **MUST** have identical values for those properties. The `mode` must be TRIANGLE_FAN, TRIANGLE_STRIP, LINE_LOOP, or LINE_STRIP." | ||
| }, | ||
| "indices": { | ||
| "allOf": [ | ||
| { | ||
| "$ref": "glTFid.schema.json" | ||
| } | ||
| ], | ||
| "description": "The index of the accessor that contains the vertex indices", | ||
| "gltf_detailedDescription": "The index of the accessor that contains the vertex indices. The accessor **MUST** have `SCALAR` type and an unsigned integer component type. The indices are permitted to include the maximal index value for the component type, indicating the start of a new primitive." | ||
| }, | ||
| "name": {}, | ||
| "extensions": {}, | ||
| "extras": {} | ||
| }, | ||
| "required": [ | ||
| "primitives", | ||
| "indices" | ||
| ] | ||
| } |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.