Officially document + prove support for KHR_mesh_primitive_restart#13634
Officially document + prove support for KHR_mesh_primitive_restart#13634markschlosseratbentley wants to merge 5 commits into
Conversation
… and add a Sandcastle for visual verification of support.
|
Thank you for the pull request, @markschlosseratbentley! ✅ We can confirm we have a CLA on file for you. |
|
|
||
| const models = { | ||
| "Hilbert Curve (LINE_STRIP, 32-bit indices)": { | ||
| url: "../../SampleData/models/PrimitiveRestart/PrimitiveRestartLineStrip.glb", |
There was a problem hiding this comment.
I touched base with @donmccurdy on the inclusion of these test assets in this dev Cesium Sandcastle and he seemed to think it was fine to include them. However, we were not sure how Cesium-included assets are licensed in general. Anyone have any insights?
Context: these test assets were created by @donmccurdy and were provided as test data for this Khronos spec PR: KhronosGroup/glTF#2569
There was a problem hiding this comment.
I don't know the answer, and am not a lawyer, but would think that unless there is specific license information for a model, the "root" license (Apache 2) would apply.
The main question might therefore be: Under which license would Don like to publish them?
(The point is: I think that there could be some README.md or LICENSE.txt in that folder with whatever license should apply. At least that's done for some of the 'Specs' models, e.g. https://github.com/CesiumGS/cesium/blob/0d0c35fad1cc05ed0560f0d1ec6a9197baaef84e/Specs/Data/Models/glTF-2.0/AnimatedTriangle/README.md )
And now for something completely different: I don't see a difference between the WebGL 1 and 2 versions in terms of primitive restart. (There is a difference, in terms of (anti)aliasing, so I think that they are indeed different contexts, but the geometry looks the same for me...)
There was a problem hiding this comment.
@javagl Interesting, thanks for the webgl1 + 2 observation. I tested on Firefox on macOS. What browser/OS are you using?
There was a problem hiding this comment.
The main question might therefore be: Under which license would Don like to publish them?
I'm comfortable contributing these under any license conventional for non-code assets in CesiumJS. I might suggest CC BY if there's no prior convention.
If there are no objections, I can just add that license to these files as XMP data (gltf-transform xmp in.glb out.glb), no need for sidecar files.
There was a problem hiding this comment.
@markschlosseratbentley This was on Windows 11 with some AMD Radeon (Laptop) card (on Chrome, if that might matter). Of course, it's nothing that affects this PR. It might even be an AMD driver bug 🤪 and things unexpectedly working is a nice "problem" to have.
@donmccurdy No strong preference (details are up to you anyhow) but... 1. for that license information to even be accessible, one needs a library/loader/viewer that supports the extension, and 2. one has to explicitly and dedicatedly look for it, exactly there (which isn't self-evident - I cannt remember having seen license infos embedded in XMP).
There was a problem hiding this comment.
Small addendum: I haven't looked at the details of the models, but for the other models, there is the expected difference (i.e. the rendering is "broken" on WebGL 1). Only the "hilbert curve" is working. (Are the other ones using non-32-bit indices by any chance? That might be a path to an explanation...)
There was a problem hiding this comment.
I believe the Hilbert curve is the only UNSIGNED_INT model and others are 16-bit, which indeed could explain things. After some research, on ANGLE/D3D11 (working theory):
- D3D11 strip-cut appears to be always on (
0xFFFF/0xFFFFFFFFper index format, no obvious disable API). Found some docs here. - WebGL 1 has no primitive restart, so
0xFFFFmust act as a normal vertex index, but D3D11 would cut on it. ANGLE therefore rewrites 16-bit buffers containing0xFFFFas 32-bit, casting each0xFFFFto0x0000FFFF(see ANGLEUsePrimitiveRestartWorkaroundcode here). No cut fires; the value is fetched as vertex 65535 (out of range), resulting in broken rendering... - UNSIGNED_INT is excluded from that workaround so
0xFFFFFFFFhits the always-on cut and restart coincidentally works.
Based on this, WebGL 1 behavior is implementation-defined / undefined: macOS Firefox/Chrome render nothing, but Safari renders correctly (Metal probably behaves similar to D3D11 in this regard...).
I will update this PR's docs to clarify webgl1 behavior is "implementation-defined / undefined."
There was a problem hiding this comment.
That's quite some archeology there 🙂 Given that WebGL 1 support in CesiumJS is ... maybe not completely dropped, but quickly phasing out, and everything that is not running on Windows 3.1 and Mosaic supports WebGL 2 anyhow, it's just a matter of setting the expectations right for people with really old setups.
There was a problem hiding this comment.
There's also .asset.extras.license, which might be more widely-used than the XMP extension (Sketchfab exports used extras, in particular). But no objection to a separate license file, in that case I'd suggest this one:
https://github.com/KhronosGroup/glTF-Sample-Assets/blob/main/LICENSES/CC-BY-4.0.txt
There was a problem hiding this comment.
Thanks @donmccurdy and @javagl. Based on this licensing discussion, I additionally followed what I found to be an existing repo convention: added a CC-BY 4.0 entry to the root LICENSE.md (matching other Apps/SampleData models like "Perc Lead Mine"). I did this because that LICENSE.md file is clearly distributed and accessible in a release zip of CesiumJS. Providing license alongside distribution for CC-BY 4.0 is required.
I also placed a README.md in the model folder, which hasn't always been done it seems, but makes sense for clarity, I think.
@donmccurdy I credited you in both places, so LMK if you have any issues with this.
| * {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit/README.md|KHR_materials_unlit} | ||
| * </li> | ||
| * <li> | ||
| * {@link https://github.com/KhronosGroup/glTF/pull/2569|KHR_mesh_primitive_restart} |
There was a problem hiding this comment.
Since this PR does not include any functional changes to CesiumJS, I did not see a need to include an entry in CHANGES.md, leaving it just to inline documentation here. However, I am open to adding a CHANGES.md entry if someone thinks it's necessary and/or desirable. @ggetz?
There was a problem hiding this comment.
I agree it isn't strictly necessary – but I'd be tempted to include it, as many CesiumJS users probably aren't aware of the extension otherwise and might benefit from knowing that it exists and CesiumJS supports it.
Something like:
- Added support for the [`KHR_mesh_primitive_restart`](https://github.com/KhronosGroup/glTF/pull/2569) glTF extension. [#13634](https://github.com/CesiumGS/cesium/pull/13634)
There was a problem hiding this comment.
Thanks for the feedback; I think this makes sense. Added.
donmccurdy
left a comment
There was a problem hiding this comment.
Left minor comments only - LGTM!
| * {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit/README.md|KHR_materials_unlit} | ||
| * </li> | ||
| * <li> | ||
| * {@link https://github.com/KhronosGroup/glTF/pull/2569|KHR_mesh_primitive_restart} |
There was a problem hiding this comment.
I agree it isn't strictly necessary – but I'd be tempted to include it, as many CesiumJS users probably aren't aware of the extension otherwise and might benefit from knowing that it exists and CesiumJS supports it.
Something like:
- Added support for the [`KHR_mesh_primitive_restart`](https://github.com/KhronosGroup/glTF/pull/2569) glTF extension. [#13634](https://github.com/CesiumGS/cesium/pull/13634)
Description
Officially clarifies support for
KHR_mesh_primitive_restartin CesiumJS. This extension allows many line strips, line loops, triangle strips, or triangle fans to be batched into a single glTF primitive, with inline "restart" index values (the max value for the index component type) separating the topological primitives.Support was already de facto working. The loader passes inline restart values through untouched, WebGL 2 interprets them natively (
PRIMITIVE_RESTART_FIXED_INDEXis always on for indexed draws), and theextensionsRequiredwhitelist entry was added in #13478. This PR makes support official with no loader changes. See actual changes in below section.Screenshot demonstrating
KHR_mesh_primitive_restartfunctioning properly in a CesiumJS Sandcastle.Dev Sandcastle
Check out the deployed Dev Sandcastle here.
Changes
GltfLoaderSpectests verifying restart values survive loading intact and the styling data loads alongside them.Model.jsJSDoc: addsKHR_mesh_primitive_restartto the supported extensions list (with a WebGL 1 caveat, see below) and fixes the staleEXT_mesh_primitive_restartlink.Known limitations
requestWebgl1: trueor automatic fallback), restart indices are treated as ordinary vertex indices and affected primitives render incorrectly. A CPU-side index-splitting fallback is possible but out of scope for at least this PR. This limitation is documented in theModel.jsJSDoc; demonstrable via the dev sandcastle's context toggle.Issue number and link
Fixes #13629
Testing plan
npx gulp test --includeName "KHR_mesh_primitive_restart"— 2 new specs pass; the 6 existingEXT_mesh_primitive_restartspecs still pass.Author checklist
CONTRIBUTORS.mdCHANGES.mdwith a short summary of my changeAI acknowledgment
If yes, I used the following Tools(s) and/or Service(s):
GitHub Copilot
If yes, I used the following Model(s):
Claude Fable 5