How to update materials dynamically to a character?

I want to update the materials dynamically like,

If I click on Shirt Image, Shirt material should update
else if I click on pant image, it should update in materials of a character,

Here I get .glb files of images,
I am able to get how should I render it??

Here is my reference image

After loading a model in your application, you will be able to get the material by name or id and change its properties.

First you should load your model following .glTF File Loader Plugin | Babylon.js Documentation

@PirateJC, this topic is often requested, I wonder if we could add a quick blurb in the doc ?

1 Like

I am not able to get how to load .glb file which I had along with a different mesh

I want to load that .glb in a mesh

Like I tried this:

material = scene.getMeshByName("Layered_sweater");
        SceneLoader.ImportMesh("", "./expo-files/models/characters/male/black jacket.glb", "", scene, function (newMeshes) {
          var mesh = newMeshes[1];
          material = mesh;
});

But its not working out

You can’t assign a mesh to a material, meshes and materials are different things

1 Like

@carolhmj In the above code I mentioned,
I got mesh from getMeshByName(“my_mesh_name”) of the material I want to change,
and after loading .glb file in ImportMesh, I got mesh of the .glb file,

So, while trying to replace with new mesh its updating in json data but not rendering in UI

Can you describe your situation a bit more? What meshes do you have? It would be preferable to show us a Playground with what you’re doing.

I not able show it in playground, as the files which I want to rendering on click are in my local sys, so here is my total code:

SceneLoader.ImportMeshAsync("", path, object.name, scene).then((result) => {
    var mesh = result.meshes[0];

    const advancedTexture = AdvancedDynamicTexture.CreateFullscreenUI("UI");

    var shirt_mesh;

    if (shirt_images.length) {
      let UIPanel = new StackPanel();
      UIPanel.width = "420px";
      UIPanel.fontSize = "20px";
      UIPanel.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
      UIPanel.verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
      advancedTexture.addControl(UIPanel);

      shirt_images.forEach((shirt) => {
        // Textures
        let text_button = Button.CreateImageOnlyButton(shirt.file_path, `./expo-files/models/characters/male/${shirt.image_path}`);
        text_button.paddingTop = "10px";
        text_button.width = "100px";
        text_button.height = "100px";
        text_button.background = "white";
        text_button.cornerRadius = 10;

        // UI alignment for textures
        UIPanel.addControl(text_button);

        text_button.onPointerUpObservable.add(() => {
          shirt_mesh = scene.getMeshByName("Layered_sweater");
          SceneLoader.ImportMesh("", "./expo-files/models/characters/male/black-jacket.glb", "", scene, function (newMeshes) {
            var mesh = newMeshes[1];
            shirt_mesh = mesh;
          });
        });
      });
    }
  });

Actualy here I am trying to rendering .glb file dynamically based on based on the image I clicked,

Like, I load .glb file of the image which I click with ImportMesh and trying to render the mesh of character.
I mesh of the character is updating with the new .glb mesh, but not rendering in UI

here is my UI video reference:
https://drive.500apps.com/6b80f9fa

You can upload your assets to a file service and use them on the Playground: Using External Assets In the Playground | Babylon.js Documentation (babylonjs.com)

1 Like

What exactly is happening or not happening?
Are your panels created from the length of your shirt_images. Do you have the correct number of panels and do they stack correctly (not one on top of the other)?
If so, what happens to the image? Does it display only the first image in the first panel or the first in all panels? Does it display at all?

I mean, if @carolhmj cannot spot it just like that from your code extract, I don’t know who can (and certainly not me).
We do not need everything in the PG but without a PG, I think the only thing we can do is to create our own duplicate to understand what’s going on here. And personally, I’d rather spare this time for something else (sry). But then with a PG, I believe the answer will come to you rather quickly…

Here I am trying to change the mesh (Shirt) of the character by click on image,
But it’s appending as mesh on another mesh, instead of replacing the mesh

Here is the PG similiar to my code:

You are trying to change the mesh instead of changing just the albedoTexture of its material.
Example - https://playground.babylonjs.com/#Z6SWJU#660

But I want to change the total mesh like along with shape of material,
not like just texture

In this case you may need to reparent your shirt to the main character.
Here - https://playground.babylonjs.com/#Z6SWJU#661 - old shirt mesh and the root of new shirt are disposed. Be aware that you’ll have a new shirt mesh added every time with button click, so you may need additional logic to prevent it.

Thank you