# Multi-Materials

> Learn how to use Babylon.js Multi-Materials.

Source: https://doc.babylonjs.com/features/featuresDeepDive/materials/using/multiMaterials

A multi-material is used to apply different materials to different parts of the same object, as you can see below.

![Multi Material Sphere](https://doc.babylonjs.com/img/how_to/Materials/multi.webp)

To define a multi-material, you first have to define some standard materials:

```javascript
const material0 = new BABYLON.StandardMaterial("mat0", scene);
material0.diffuseColor = new BABYLON.Color3(1, 0, 0);
material0.bumpTexture = new BABYLON.Texture("normalMap.jpg", scene);

const material1 = new BABYLON.StandardMaterial("mat1", scene);
material1.diffuseColor = new BABYLON.Color3(0, 0, 1);

const material2 = new BABYLON.StandardMaterial("mat2", scene);
material2.emissiveColor = new BABYLON.Color3(0.4, 0, 0.4);
```

Then you can create a multi-material in order to gather them all:

```javascript
const multimat = new BABYLON.MultiMaterial("multi", scene);
multimat.subMaterials.push(material0);
multimat.subMaterials.push(material1);
multimat.subMaterials.push(material2);
```

You are now able to assign the multi-material to your mesh:

```javascript
const sphere = BABYLON.MeshBuilder.CreateSphere("Sphere0", { segments: 16, diameter: 3 }, scene);
sphere.material = multimat;
```

But if you do that, you will see that the sphere will only use the first submaterial (the red bumped one). This is because by default a mesh is designed to use only one material.

You can specify which part of the mesh uses a specific material by using the _subMeshes_ property. By default, every mesh comes with only one submesh that covers the entire mesh.

To define multiple submeshes, you just have to use this code:

```javascript
sphere.releaseSubMeshes();
const verticesCount = sphere.getTotalVertices();

new BABYLON.SubMesh(0, 0, verticesCount, 0, 900, sphere);
new BABYLON.SubMesh(1, 0, verticesCount, 900, 900, sphere);
new BABYLON.SubMesh(2, 0, verticesCount, 1800, 2088, sphere);
```

In this case, you will have 3 parts:

- One starting from index 0 to index 900
- One starting from index 900 to index 1800
- One starting from index 1800 to index 3880

A submesh is defined with:

- The index of the material to use (this index is used to find the correct material inside the _subMaterials_ collection of a multi-material)
- The index of the first vertex and the count of vertices used (to optimize things for collisions, for instance)
- The index of the first index to use and the index count
- The parent mesh

So with the code above, you can use the first material on the top part of the sphere, the second material on the middle part and the last material on the bottom part of the sphere.

- [Playground: Sphere With Multi-Material](https://playground.babylonjs.com/#2Q4S2S#268) - Simple example of applying a multi-material to a sphere.

## With Merged Meshes

When you [merge meshes](https://doc.babylonjs.com/features/featuresDeepDive/mesh/mergeMeshes) together, setting the final parameter _multiMultiMaterial_ to true, the `subMeshes` array is automatically created with all of the merging meshes' subMeshes. Each subMesh's material is also included in the resulting mesh's new multiMaterial. This feature ignores the parameter (`subdivideWithSubMeshes`).

- [Playground: Multi-Material With Merged Meshes 1](https://playground.babylonjs.com/#INZ0Z0#59) - Simple example of applying a multi-material to merged meshes.

When you [merge meshes](https://doc.babylonjs.com/features/featuresDeepDive/mesh/mergeMeshes) together with the second to last parameter (`subdivideWithSubMeshes`) set to true, but the last parameter (`multiMultiMaterial`) left as false, the subMeshes array is automatically created with each merging mesh as a submesh of the new mesh. You must assign the correct subMesh index to the correct material index.

When you form `mergedMesh` by merging meshes in this array order [mesh1, mesh2], and the multiMaterial's `subMaterials` array contains materials in the order [mat1, mat2], then for the subMesh from `mesh2` to have material `mat2`, you need to set

```javascript
mergedMesh.subMeshes[1].materialIndex = 1;
```

- [Playground: Multi-Material With Merged Meshes 2](https://playground.babylonjs.com/#INZ0Z0#6) - Simple example of applying a multi-material to merged meshes.
