Replacing material/multi-material won't work

Hello there,

I have built a custom material with NME and it works fine for the majority of my models (by doing the replacement), but I have a particular case where one of my models has 2 materials (window and chassis).
I’m able to conserve the standard material of the window (semi-transparent) of my model but the chassis (which is the second material in this case) is never applied.
I tried looping through the scene and replacing the second material by my NME material, but my model remains white. I also tried creating a multi-material and pushing both of them and replacing by such, but that doesn’t work either.

Here’s a little code snippet

const multimat:BABYLON.MultiMaterial = new BABYLON.MultiMaterial(‘multi’, this._scene);
for (let i = 0; i < this._scene?.materials.length!; i++) {
if (this._scene?.materials[i].name.includes(‘CarBody’)) {
multimat.subMaterials.push(this._nodeMaterial);
}
if (this._scene?.materials[i].name.includes(‘Window’)) {
const mat = this._scene.getMaterialByName(this._scene?.materials[i].name) as StandardMaterial;
multimat.subMaterials.push(mat);
}
}

    if (multimat.subMaterials.length === 0) {
        this._currentCarModel!.material = this._nodeMaterial;
    } else {
        this._currentCarModel!.material = multimat;
    }

Any ideas on what could be wrong?

I don’t think we will be able to help without a repro.

Are you able to setup a repro in the Playground?

Note that multi-materials can be used only for meshes with sub-meshes: is _currentCarModel mesh made of several sub-meshes?

2 Likes

Hi Evgeni,

The _currentCarModel is not composed by multiple submeshes. So single meshes can’t have multiple materials like Unity does?

A submesh is just a contiguous set of vertices within a single BABYLON mesh. A mesh with submeshes is usually built with an exporter to get the vertices of each material to be contigious, and a Babylon exporter at that. GLB files do not support mult-materials. GLB exporters actually break up meshes into meshes each with one material.

If you are still reading, I am assuming you have a file .BABYLON file, not .GLB. Seems like it would just easier to keep the same multimaterial & replace the members, rather than create a new multimaterial.

Maybe I should give the full context to the conversation so things make sense.
In my first iteration, I exported my models from within Unity using the BABYLON plugin, so I’m using GLB files. That was easy because I was using the standard material.

There was the need to change the color of the model, so I created a NME with my custom shader and did the swap via code and that worked for the majority of the models, but some of them have multiple meshes with their respective material (I had to adapt the code a little bit to find the right mesh to be replaced by my NME shader) and some of them have a unique mesh with multiple materials. This last one is the one I’m trying to overcome right now.

So my questions are, is there a way to retrieve all the materials of a mesh (I had to go through the scene instead) and replace the one I want?
I tried, replacing it after loop through all materials and grabbing a reference to the one I needed and also tried generating the multi-material with the correct materials, but both solutions failed.

Is the only viable solution to split the 3D model itself?

Cheers!

There is only one material per mesh, mesh.material. That material can be a BABYLON.MultiMaterial, so that can be tested for:

if (mesh.material instanceOf BABYLON.MultiMaterial) {
     // change out the subs
    // should not be here for a GLB defined mesh
} else {
    // replace mesh.material
}

Your terms model & models do not seem consistent. What is a model? A mesh or a scene?

If you are now trying to replace the material of a mesh with a MultiMaterial, it had better already have a multimaterial as the material, otherwise how could it possibly know which set of contiguous vertices go with each submaterial?

Hey JCPalmer,

Thanks for the help. I guess I’m not fully understanding the concept then, cause if I export my car model (one single mesh for the chassis with the windshield) inside sandbox, I can see it has both my standard materials in it (chassis and windshield), and when checking if the material is an instance of MultiMaterial via code, it still says it’s single.

Cheers!

Ok, by looking at the sandbox I figured out.

It seems like the exporter will just create the submeshes for us, so I just had to find the right submesh to replace it’s material. Now it’s working.

1 Like