Support for BENTLEY_materials_line_style glTF Extension#13110
Support for BENTLEY_materials_line_style glTF Extension#13110danielzhong wants to merge 47 commits intomainfrom
Conversation
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…lZ/BENTLEY_materials_line_style
…aterials_line_style
|
Thank you for the pull request, @danielzhong! ✅ We can confirm we have a CLA on file for you. |
|
@lilleyse This has made a bunch of progress, so would you mind taking another pass on it? cc @danielzhong |
Specs/Data/Models/glTF-2.0/StyledLines/BENTLEY_materials_line_style.gltf
Show resolved
Hide resolved
There was a problem hiding this comment.
Pull request overview
This PR implements support for the proposed BENTLEY_materials_line_style glTF extension, enabling CAD-style line visualization with customizable width (in screen pixels) and 16-bit dash patterns. The implementation refactors the existing EXT_mesh_primitive_edge_visibility extension from line primitives to quad-based rendering to support variable line widths, as WebGL doesn't support line widths greater than 1. Additionally, the PR addresses silhouette normal decode issues and extends edge visibility loading to honor material colors and line-string overrides.
Changes:
- Added support for the
BENTLEY_materials_line_styleglTF extension withwidthandpatternproperties for lines and edges - Refactored
EXT_mesh_primitive_edge_visibilityfromgl_linesto tessellated quads (4 vertices, 2 triangles per edge) to enable variable line width rendering - Extended edge visibility to support material color overrides and line strings with cumulative distance attributes for stable pattern scaling
Reviewed changes
Copilot reviewed 20 out of 23 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
packages/sandcastle/gallery/styled-gltf-lines-dev/* |
New Sandcastle example demonstrating styled glTF lines with custom width and dash patterns |
packages/engine/Specs/Scene/Model/*.js |
Added comprehensive unit tests for line style extension, edge visibility quad rendering, and material color overrides |
packages/engine/Source/Shaders/Model/*.glsl |
Implemented vertex and fragment shader stages for line style rendering, edge expansion, and pattern application |
packages/engine/Source/Scene/VertexAttributeSemantic.js |
Added CUMULATIVE_DISTANCE semantic for line pattern distance tracking |
packages/engine/Source/Scene/ModelComponents.js |
Added lineWidth, linePattern, and edgeVisibility properties to Material and Primitive components |
packages/engine/Source/Scene/Model/*.js |
Implemented quad-based edge geometry generation, material pipeline integration, and edge color attribute handling |
packages/engine/Source/Scene/GltfLoader.js |
Added loading logic for BENTLEY_materials_line_style extension and edge visibility line strings |
Specs/Data/Models/glTF-2.0/StyledLines/*.gltf |
Test data files demonstrating the line style extension |
CHANGES.md |
Updated changelog with new features |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@jjhembd fyi |
|
@danielzhong thanks for this PR! It is a fairly big change, so it will take me some time to finish the review. I should have some feedback early next week. Let me know if you need anything sooner. |
|
Admittedly, I'm a bit surprised that const viewer = new Cesium.Viewer("cesiumContainer", {
infoBox: false,
selectionIndicator: false,
shouldAnimate: true,
});
async function createModel(url, height) {
const transform = Cesium.Transforms.eastNorthUpToFixedFrame(
Cesium.Cartesian3.fromDegrees(-75.152408, 39.946975, height)
);
const model = await Cesium.Model.fromGltfAsync({
url: url,
modelMatrix: transform,
// TEST debugWireframe
enableDebugWireframe: true,
debugWireframe: true
});
viewer.scene.primitives.add(model);
model.readyEvent.addEventListener(() => {
viewer.scene.camera.flyToBoundingSphere(
model.boundingSphere, {
duration: 0
});
});
}
createModel("http://localhost:8003/line.point_style/7-1-0.glb", 20.0);I haven't looked at the implementation here, but know that A detail: |
@javagl Could you let me know which tool you used for validation and which files show this error? I ran them through |
Apologies for the false alert here: I ran the test with the files that had been attached in the first comment (line_style.zip and line&point_style.zip), and they still contained the errors. But I now checked the ones that are part of this PR, and they do not cause any errors 👍 |
| @@ -0,0 +1,36 @@ | |||
| <!doctype html> | |||
There was a problem hiding this comment.
Hi @danielzhong, I am looking at this now and plan to give more feedback tomorrow.
One initial comment: This Sandcastle HTML doesn't follow the pattern of the new Sandcastle files. Can we replace this with a more minimal file like the others? Most of this boilerplate should be taken care of by the sandcastle build step.
|
Hi @danielzhong, I am looking through this in a little more depth. Can you help me with a couple big-picture questions here? Change to existing edge rendering examplesThe PR description mentions this:
The testing plan doesn't mention how to verify that old examples using Interaction between definesIntuitively, I would expect a hierarchy something like this: #if (defined(EDGES_VISIBLE))
// Process attributes & uniforms related to edge rendering
// ...
#if (defined(VARIABLE_EDGE_WIDTH))
// Process attributes & uniforms related to variable edge width
#endif
#if (defined(EDGE_LINE_PATTERN))
// Process attributes & uniforms related to line patterns like dashes etc
#endif
#endifBut inside #if defined(HAS_LINE_PATTERN) && !defined(HAS_EDGE_VISIBILITY)
const float maskLength = 16.0;
// More line pattern processingWhy would we bother with a line pattern if the edges are not visible? I assume |
Hi, thanks for taking the time to review this.
This test file has not been changed, and the previous unit tests were not modified either. I’ve verified that it still renders correctly. In addition, I’ve included another demo for edge visibility in the PR description. There is no distinction between "old" and "new"
The |
Description
BENTLEY_materials_line_stylegltfmaterial extension in CesiumJS. This extension enables CAD-style line visualization with variable width and dash patterns. The proposed specification can be found here.in this commit: fe13f48
EXT_mesh_primitive_edge_visibilitygltf extension by switching fromgl_linesto tessellated quads rendered asgl_triangles, enabling line-width support.pixelsPerWorldoverczm_metersPerPixelto match iTwin implementation.Overview (
BENTLEY_materials_line_style)width: 5,pattern: 61680The BENTLEY_materials_line_style extension allows glTF materials to specify:
width: Line thickness in screen pixelspattern: A 16-bit repeating on/off dash pattern (each bit = 1 screen pixel)This PR allows CesiumJS to process and apply the above extension when loading glTF files. This means lines and edges will be able to have customizable width and pattern properties specified and respected in CesiumJS when loaded via glTF.
Implementation Details:
Because variable line width is required (and many graphics APIs including WebGL do not support
gl_lineprimitives with width > 1), this PR refactors theEXT_mesh_primitive_edge_visibilityimplementation to use quad-based rendering instead of the previous gl_line approach. Each line segment is tessellated into a quad (two triangles) that is dynamically expanded perpendicular to the edge direction based on the material'swidthproperty.The 16-bit dash pattern is applied in the fragment shader by testing individual bits against the screen-space position along the line, providing pixel-perfect pattern rendering that remains stable under camera movement.
Changes:
Added support for
BENTLEY_materials_line_styleinGltfLoader.jsandMaterialPipelineStage.jsRefactored edge rendering from line primitives to quad-based geometry in
EdgeVisibilityPipelineStage.jsImplemented vertex shader expansion logic for variable-width lines in
EdgeVisibilityStageVS.glslImplemented fragment shader pattern matching using bit extraction in
EdgeVisibilityStageFS.glslAdded
u_lineWidthandu_linePatternuniforms to the edge rendering pipelineTo test these changes locally:
http-server ./ --cors=X-Correlation-Idline_style.zip
line&point_style.zip
npm run build-sandcastleand in sandcastle search for theStyled glTF Linesexample.Note:
This PR may include changes from other currently open PRs, this PR was built on top of the following PRs:
EXT_mesh_primitive_edge_visibility's material and line string:(This PR supersedes the previous PR (#12859). All changes have been moved here and mainly focus on completing the material and line string support for EXT_mesh_primitive_edge_visibility. Please refer to the links for more details.)
For line patterns & cumulative distance:
If the demo does not show density changes while zooming, it’s usually because the camera frustum width isn’t changing (e.g., a trackedEntity or fixed frustum). Once frustum.width updates, the pattern density changes as expected.
For example:
Issue number and link
#12889
Testing plan
Live DEMO - orthographic polyline pattern
This demo primarily illustrates the issue described in https://github.com/iTwin/itwinjs-backlog/issues/1812. It demonstrates that the new cumulative distance has been successfully added in CesiumJS to address the problem. The demo uses an orthographic frustum, since users affected by this issue are mainly concerned with a top-down (2D) view.
Live DEMO- Edge Visibility with line pattern
This demo simply shows that line patterns work correctly with edges using the edge visibility glTF extension.
Live DEMO 3 - Edge Visibility with line pattern2
Live DEMO 4 - Edge Visibility only
Added unit tests
Added a Cesium Sandcastle sample.
Author checklist
CONTRIBUTORS.mdCHANGES.mdwith a short summary of my change