Add KHR_mesh_primitive_restart#2569
Open
donmccurdy wants to merge 3 commits intoKhronosGroup:mainfrom
Open
Conversation
This was referenced Apr 16, 2026
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Motivation
glTF 2.0 includes seven primitive modes:
0 POINTS1 LINES2 LINE_LOOP3 LINE_STRIP4 TRIANGLES5 TRIANGLE_STRIP6 TRIANGLE_FANFour of these (
LINE_LOOP,LINE_STRIP,TRIANGLE_STRIP,TRIANGLE_FAN) define topologies that may contain any number of vertices. Each glTF mesh primitive defines a single contiguous topology for these types, because primitive restart values — which would instruct the graphics API to begin a new topological primitive, without a new draw call — are disallowed by the core specification for maximum compatibility (see: WebGL 1).This PR proposes a
KHR_mesh_primitive_restartextension, which can be added to any glTF asset, removing the restriction against primitive restart values. The mechanism and implementation are intentionally very similar toKHR_mesh_quantization, which removes restrictions on particular vertex attribute component types.Primitive restart values allow a scene to contain arbitrary numbers of line loops, line strips, triangle strips, and triangle fans, without requiring arbitrary numbers of mesh primitives, along with costly processing and draw calls. This also greatly reduces the amount of JSON (primitive and accessor) definitions required to represent such scenes.
Background
The existing
EXT_mesh_primitive_restartallows primitive restart values, but does so by encoding each primitive topology as a separate glTF mesh primitive, defined in JSON and having a distinct indices accessor. The extension adds indices with restart values as metadata, allowing runtimes to stitch these primitives together as a single draw call, but the runtime must still download and parse data for the original N primitives. Unfortunately, the performance implications of this approach are not ideal. See CesiumGS#100.EXT vs. KHR
I'm open to modifying the existing
EXT_mesh_primitive_restartextension, but modifying an existing EXT extension would be an unusual step. While I believe it has only very limited implementations today, initial feedback has been on the side of avoiding changes to an existing EXT extension.For that reason, and hoping the approach here might be broadly useful for anyone using these primitive topologies in glTF 2.0, I'm proposing a simplified/optimized approach as a new extension,
KHR_mesh_primitive_restart.Fallback
If a runtime doesn't support primitive restart values, it would need to pre-process the index list. But this optimizes the extension for present-day and future use, where primitive restart support is standard, and imposes the cost of fallback only on the small (and shrinking) cases where primitive restart is not supported in hardware. I believe that's an important improvement for adoption and production use of the extension.
Fallback may not necessarily require separate draw calls for each topological primitive. Multi-draw Indirect (MDI) would be an alternative (if there exists a graphic API that supports MDI but not primitive restart values). I'm not familiar with how a path-tracing renderer would want to handle primitive restart indices.
Samples
PrimitiveRestartLineStrip.glb.zip
In some viewers (including https://gltf-viewer.donmccurdy.com/) the model will display correctly without any modifications to support
KHR_mesh_primitive_restart, because primitive restart is already enabled by default by the WebGL 2 API.Implementations