Target and update a GLB's material like Model-Viewer does

Hi! I understand Model-Viewer Model Editor uses ThreeJS and I was curious as to how it allows for the targeting and updating of materials in a GLB. When I load my GLB into it’s editor, it allows me to target the materials:

When I want to update materials in ThreeJS I have to traverse the nodes to find the materials manually and match them.

For example, the Box material above is actually 6 nodes which would each need updating manually using the traverse method in ThreeJS. Using ModelViewer I can create a single material and update the box in one go.

My question is: does ModelViewer leverage ThreeJS to target these materials as a group, or is it doing its own magic to achieve this?

Hope that makes sense!

if the box material is shared by all 6 meshes , changing one will affect the others , traverse just gets you all the individual usages

To get a similar list traverse once and just make a js object to store all unique materials

// assuming material names exists & are unique
const materials={}
    if (object.isMesh) {
          materials[] = object.material

1 Like

It’s using three.js, and traversing the scene graph as you suggest. You can reuse materials across many Meshes in three.js, and then update them in one go, I think that’s probably what’s happening here.

There are other ways you might do the same thing (see GitHub - donmccurdy/glTF-Transform-View: Syncs a glTF-Transform Document with a three.js scene graph.) but traversing the scene graph to gather a list of unique materials is a totally reasonable option.

1 Like

Thanks guys - in my implementation, I don’t know what the name of the material to match will be; it’s different for each GLB we might load in. However, I discovered that by using gltf.parser.getDependencies() I can get a list of the materials and use the names to match the nodes as @orion_prime mentions by using the traverse method.
Hopefully I’m using as it was intended. Thanks again!