Skip to content

EXT_mesh_primitive_edge_visibility's material and line string#13002

Closed
danielzhong wants to merge 21 commits into
mainfrom
daniel/edge_visibility_material
Closed

EXT_mesh_primitive_edge_visibility's material and line string#13002
danielzhong wants to merge 21 commits into
mainfrom
daniel/edge_visibility_material

Conversation

@danielzhong

@danielzhong danielzhong commented Oct 27, 2025

Copy link
Copy Markdown
Member

Description

This is a follow up PR to #12859. Primarily implementing the missing functionality for the material and line string section of EXT_mesh_primitive_edge_visibility:

  • Parse EXT_mesh_primitive_edge_visibility materials and lineStrings during glTF load, extracting baseColorFactor as the default edge color and honoring per-lineString overrides.

  • Expand the edge visibility pipeline to merge the bitfield and line-string edge data, generate optional edge-color attributes, and pass them through to the edge-rendering shader.

  • Update the edge fragment stage to use the override colors from material section

Material:

Defines an accessor to the glTF material that supplies the edge color. This field is optional, when it is omitted the edges fall back to the mesh’s per‑vertex colors.

LineStrings

Defines accessors containing one or more line strings. Each entry may reference its own material; if not specified, the material defined in the section above is used, or otherwise the mesh’s vertex colors. Edges listed in this section must not be duplicated in the visibility bitfield (Handling during encoding: https://github.com/iTwin/imodel-native-internal/pull/888).

For more details please check:
EXT_mesh_primitive_edge_visibility README: Edge Visibility

Issue number and link

Previous PR: #12859
backlog issues: https://github.com/iTwin/itwin-graphics-backlog/issues/742
EXT_mesh_primitive_edge_visibility README: Edge Visibility
Khronos Group PR: Edge Visibility

Testing plan

Example Test files:

Two triangles: both have red fill color — one with a green outline and the other with a blue outline.
Snipaste_2025-10-26_22-51-36

example.zip

"materials": [
  {
    "pbrMetallicRoughness": {
      "metallicFactor": 0.0
    },
    "doubleSided": true
  },
  {
    "pbrMetallicRoughness": {
      "baseColorFactor": [0.0, 0.0, 1.0, 1.0],  // blue
      "metallicFactor": 0.0
    },
    "doubleSided": true
  },
  {
    "pbrMetallicRoughness": {
      "baseColorFactor": [0.0, 1.0, 0.0, 1.0],  // green
      "metallicFactor": 0.0
    },
    "doubleSided": true
  }
]

"EXT_mesh_primitive_edge_visibility": {
  "lineStrings": [
    { "indices": 5, "material": 1}, 
    { "indices": 6, "material": 2 }
  ]
}

2. Expecting: 1 blue cylinder (Both outline and fill color are the same)
image

cylinder.zip

"EXT_mesh_primitive_edge_visibility": {
  "visibility": 5,
  "silhouetteNormals": 6
}

Live DEMO

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
  • Live DEMO
  • Add example glb file to the repo

@github-actions

Copy link
Copy Markdown
Contributor

Thank you for the pull request, @danielzhong!

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

@danielzhong
danielzhong requested a review from Copilot October 27, 2025 14:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull Request Overview

This PR implements missing material and line string functionality for the EXT_mesh_primitive_edge_visibility glTF extension, extending edge rendering capabilities to support per-edge colors and explicit line string definitions.

  • Parses materials and lineStrings sections from the extension, extracting edge colors from baseColorFactor and supporting per-lineString color overrides
  • Updates edge visibility pipeline to merge bitfield and line-string edges, generate edge-color attributes, and apply material colors in the shader
  • Simplifies edge fragment shader to use override colors and remove debug color coding

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
EdgeVisibilityStageFS.glsl Simplified fragment shader to apply edge colors from attributes instead of debug color coding
ModelComponents.js Added edgeVisibility property to Primitive for storing extension data
EdgeVisibilityPipelineStage.js Extended pipeline to handle line strings, generate edge color attributes, and process vertex colors
GltfLoader.js Added parsing of material colors and line strings from extension during glTF load

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/engine/Source/Scene/GltfLoader.js Outdated
@danielzhong
danielzhong marked this pull request as ready for review October 30, 2025 20:06
@danielzhong
danielzhong marked this pull request as draft October 30, 2025 20:35
@danielzhong
danielzhong marked this pull request as ready for review October 30, 2025 21:52

@lilleyse lilleyse left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good @danielzhong, just a few minor comments.

return gltfLoader;
}

function parseGlb(arrayBuffer) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Are the parseGlb and createGlbBuffer helpers needed if the spec files are .gltf instead of .glb?

Comment on lines +612 to +613
!isInt8Array &&
!isInt16Array

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't think glTF allows vertex colors to be signed integers, you may not need to handle this case.

* @param {number} faceNormalBLocation Shader attribute location for face normal B
* @param {number} edgeFeatureIdLocation Shader attribute location for optional edge feature ID
* @param {number} edgeColorLocation Shader attribute location for optional edge color data
* @param {{colors:Float32Array,count:number}} vertexColorInfo Packed per-vertex colors (optional)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just checking, is this valid JSDoc? We would usually write this as a typedef

/**
 * @typedef {object} VertexColorInfo
 * @property {Float32Array} colors
 * @property {number} count
 */

 * @param {VertexColorInfo} [vertexColorInfo] Packed per-vertex colors (optional)

@danielzhong

Copy link
Copy Markdown
Member Author

Looks good @danielzhong, just a few minor comments.

Thanks for the feedback, fixed!

@markschlosseratbentley markschlosseratbentley left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@danielzhong Thank you very much for your work on this PR. Based on @lilleyse's comments and your recent pushes, this overall looks good to me.

@danielzhong

Copy link
Copy Markdown
Member Author

Closing this PR since the change is included in the new PR:
#13110

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.

4 participants