Skip to content

Conversation

@danielzhong
Copy link
Contributor

@danielzhong danielzhong commented Dec 30, 2025

Description

  1. This PR implements support for the BENTLEY_materials_line_style gltfmaterial extension in CesiumJS. This extension enables CAD-style line visualization with variable width and dash patterns. The proposed specification can be found here.
  2. This PR fixed silhouette normal decode issues: EXT_Edge_Visibility Bug in Cesium JS iTwin/itwinjs-core#8879
    in this commit: fe13f48
  3. This PR updates the EXT_mesh_primitive_edge_visibility gltf extension by switching from gl_lines to tessellated quads rendered as gl_triangles, enabling line-width support in
  4. 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

Overview (BENTLEY_materials_line_style)

width: 5, pattern: 61680
Snipaste_2025-12-30_11-30-46
Snipaste_2026-01-01_03-02-11

The BENTLEY_materials_line_style extension allows glTF materials to specify:

width: Line thickness in screen pixels
pattern: 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_line primitives with width > 1), this PR refactors the EXT_mesh_primitive_edge_visibility implementation 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's width property.

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_style in GltfLoader.js and MaterialPipelineStage.js
Refactored edge rendering from line primitives to quad-based geometry in EdgeVisibilityPipelineStage.js
Implemented vertex shader expansion logic for variable-width lines in EdgeVisibilityStageVS.glsl
Implemented fragment shader pattern matching using bit extraction in EdgeVisibilityStageFS.glsl
Added u_lineWidth and u_linePattern uniforms to the edge rendering pipeline

To test these changes locally:

  • Clone this branch.
  • Build CesiumJS and Sandcastle.
  • Run the dev server locally.
  • Host your glb/gltf test files using: http-server ./ --cors=X-Correlation-Id
  • Navigate to Sandcastle and open the gltf:
    line_style.zip
    line&point_style.zip
const viewer = new Cesium.Viewer("cesiumContainer", {
  infoBox: false,
  selectionIndicator: false,
  shouldAnimate: true,
});

function createModel(url, height) {
  viewer.entities.removeAll();

  const position = Cesium.Cartesian3.fromDegrees(
    -123.0744619,
    44.0503706,
    height
  );

  const heading = Cesium.Math.toRadians(100.0);
  const pitch = 0.0;
  const roll = 0.0;
  const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
  const orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);

  const entity = viewer.entities.add({
    name: url,
    position: position,
    orientation: orientation,
    model: {
      uri: url,
      minimumPixelSize: 128,
      maximumScale: 20000,
    },
  });

  viewer.trackedEntity = entity;
}

createModel("http://172.20.20.20:8282/3-1-0.glb", 100.0);
  • Or npm run build-sandcastle and in sandcastle search for the Styled glTF Lines example.

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.)

Implementation for BENTLEY_materials_point_style:
Waiting for this PR to be merged before removing the unnecessary changes shown in this PR:
#13093

Issue number and link

#12889

Testing plan

Author checklist

  • I have submitted a Contributor License Agreement
  • I have added my name to CONTRIBUTORS.md
  • I have updated CHANGES.md with a short summary of my change
  • I have added or updated unit tests to ensure consistent code coverage
  • I have updated the inline documentation, and included code examples where relevant
  • I have performed a self-review of my code

@danielzhong danielzhong requested a review from ggetz December 30, 2025 18:02
@github-actions
Copy link

Thank you for the pull request, @danielzhong!

✅ We can confirm we have a CLA on file for you.

@pmconne
Copy link
Contributor

pmconne commented Dec 31, 2025

Your branch appears to contain all of the changes from #13093 too. That's unintentional, right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validation error: "VALUE_NOT_IN_RANGE | Value 1 is out of range. | /bufferViews/5/byteStride"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Thanks

@danielzhong
Copy link
Contributor Author

fe13f48

Fixed silhouette normal decode issues: iTwin/itwinjs-core#8879

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants