Multi material on one mesh

I have a 3D model that I want to place several different textures on one of its layers, with the difference that their positions are different. As far as I searched, I reached the topic of multi-material, but it did not work on my code.
please help me

Three does not have a multi-layer material - you’d need to create a custom shader for that or use CanvasTexture.

1 Like

You can actually put multiple materials on a single mesh by setting .material = [ material1, material2 ] etc. and each material in the array will be assigned to the corresponding draw group on the geometry, but it’s not super well supported since it’s a little known feature.

For instance the BoxGeometry has a draw group per face so you can pass an array of six materials, one for each face.

@Zahra_Jafarpisheh You can try setting .material to an array of 2 materials, but you may have to duplicate or set up draw groups on the geometry too.

Also just in case it’s relevant… you can control some of the positioning of a texture on a model, using texture.offset and texture.repeat
https://threejs.org/docs/#api/en/textures/Texture.offset

1 Like

It does GitHub - pmndrs/lamina: 🍰 An extensible, layer based shader material for ThreeJS

Inspired by splinetool. Nobody maintains it atm but it works fine. Vanilla is exposed as well.

import { LayerMaterial, Depth } from 'lamina/vanilla'

const geometry = new THREE.SphereGeometry(1, 128, 64)
const material = new LayerMaterial({
  color: '#d9d9d9',
  lighting: 'physical',
  transmission: 1,
  layers: [
    new Depth({
      colorA: '#002f4b',
      colorB: '#f2fdff',
      alpha: 0.5,
      mode: 'multiply',
      near: 0,
      far: 2,
      origin: new THREE.Vector3(1, 1, 1),
    }),
    // Add as many layers you want and combine them with Blend-modes
  ],
})

const mesh = new THREE.Mesh(geometry, material)

The geometry of the model is of the geometry buffer type
I put this code on the geometry plane, it is completely correct, but it didn’t work on the geometry buffer
const vertexShader = `
varying vec2 vUv;

void main() {
    vUv = uv ; 
    vec4 modelViewPosition = modelViewMatrix * vec4(position, 1.0);
    gl_Position = projectionMatrix * modelViewPosition;
}

`;

const fragmentShader = `
uniform sampler2D texture1;
uniform sampler2D texture2;
varying vec2 vUv;

void main() {
    vec4 color1 = texture2D(texture1, vUv);
    vec4 color2 = texture2D(texture2, vUv);
    gl_FragColor = mix(color1, color2, 0.5);
}

`;
loader.load(‘model/GLTF/GLTF.gltf’, (gltf) => {

  gltf.scene.scale.set(5,5,5)
  gltf.scene.position.y=-5
  gltf.scene.traverse((child) => {
    if (child.isMesh) {

      if (child.name === 'Cloth_mesh_1') {

     
    console.log(child.geometry);
        const uniforms = {
          time: { value: 0 },
          texture1: { value: texture1 },
          texture2: { value: texture2 }
        };
    
        const material = new THREE.ShaderMaterial({
          uniforms: uniforms,
          vertexShader: vertexShader,
          fragmentShader: fragmentShader
        });
        child.material=material
    
      }

    }
  });

  scene.current.add(gltf.scene);
}, undefined, (error) => {
  console.error('Error loading GLTF model:', error);
});