javascriptthree.jsaframe8thwall-web

Three.js use multiple materials on one mesh


I am trying to understand how to add multiple materials to a mesh. I want to take the existing material and apply another slightly transparent material to my existing mesh. Right now, passing it as an array it just disappears. I know I am missing something, just not sure what that is. The end goal is so I can animate the opacity of the new material in/out over the existing one.

Original Material

const originalMaterial = child.material.clone();

New Material

const newMaterial = new THREE.MeshStandardMaterial({
 name: 'New Mat',
 map: newTexture,
 emissiveMap: newTextureMap,
 side: THREE.DoubleSide,
 opacity: .5,
 transparent: true
});

Combining them

child.material = [originalMaterial, newMaterial]
child.material.needsUpdate = true

Solution

  • WebGL doesn't allow for multiple materials on a single mesh. That's why the THREE.Mesh constructor only allows one geometry, and one material.

    To do what you want, you could create two meshes, with one material's transparency set to 0.5. But more frequently you would just use a single mesh, and assign variations in opacity through the .alphaMap texture. This would give you more flexibility because you can have many more transparency values on a single object, without having to create new materials for each:

    var textureLoader = new THREE.TextureLoader();
    var alphaTexture = textureLoader.load("path/to/alpha.png");
    mesh.material.alphaMap = alphaTexture;
    
    mesh.material.transparent = true; // <- don't forget this!