Apply texture for glb model

I’ve made a dodecahedron geometry in Blender, exported it as a glb, and split all faces in order to add textures on fly for them. However, when I am trying to set the face texture via the following code it doesn’t work.

textureLoader.load( 'img/test6.jpg', (texture) =>
    {
        face.material.map = texture;
        face.material.needsUpdate = true;
    }, undefined, undefined );
    face.material.side = THREE.DoubleSide;

Here I use the same texture for cube and the face.


dodecahedron.glb (8.7 KB)

Hm, what is face :thinking: ?

loader.load("models/dodecahedron.glb", function (gltf) {
    var mesh = gltf.scene;
    scene.add(mesh);
    for(let i = 0; i< mesh.children.length; i++)
    {
        mesh.children[i].material = mesh.children[i].material.clone();
    }
    var face = mesh.children[6];
  1. Please use formatted code (there’s a button in the post editor, that lets you select which part of the post is code.) It’s easier to read.
  2. Are you sure face exists? (You can console.log it and see if it’s defined.)
  3. Make sure your texture is loaded - you can see that in devtools Network panel (there should be a request for img/test6.jpg.) face.material.needsUpdate = true; isn’t really necessary, if you change map in the material it should apply instantly, as long as the image is loaded.

Yes, it exists, I am even able to successfully change its color. The texture is loaded correctly, as you can see on my cube.

In this case it won’t probably be possible to help you without seeing the code - since the code you shared looks fine and should be working. Can you create a jsfiddle / codepen showcasing the issue?

var container = document.getElementById("container");
var renderer, scene, camera;
var mesh;
var light, orbit;
window.addEventListener("load", init);
function init() {
  renderer = new THREE.WebGLRenderer({
  });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  container.appendChild(renderer.domElement);
  scene = new THREE.Scene();
  camera = new THREE.PerspectiveCamera(
    45,
    window.innerWidth / window.innerHeight,
    1,
    10000
  );
  camera.position.z = 20;
  camera.position.y = 10;
  orbit = new THREE.OrbitControls(camera, renderer.domElement);
  light = new THREE.DirectionalLight(0xffffff);
  light.position.set(0, 10, 30);
  light2 = new THREE.DirectionalLight(0xffffff);
  light2.position.set(10, 0, 30);
  light3 = new THREE.DirectionalLight(0xffffff);
  light3.position.set(0, 10, -30);
  light4 = new THREE.DirectionalLight(0xffffff);
  light4.position.set(0, -10, 0);

  scene.add(light);
  scene.add(light2);
  scene.add(light3);
  scene.add(light4);

  var amb = new THREE.AmbientLight( 0x404040, 1 )
  scene.add(amb); // soft white light

  loadGLTF();

  window.addEventListener("resize", onWindowResize, false);
  onWindowResize();
  animate();
}

function loadGLTF() {
  var textureLoader = new THREE.TextureLoader();
  var loader = new THREE.GLTFLoader();
  loader.load("models/dodecahedron.glb", function (gltf) {
    var mesh = gltf.scene;
    scene.add(mesh);
    for(let i = 0; i< mesh.children.length; i++)
    {
        mesh.children[i].material = mesh.children[i].material.clone();
    }

    var face = mesh.children[6];

    var geometry2 = new THREE.BoxGeometry( 10, 10, 10 );

    textureLoader.load( 'img/test5.jpg', (texture) =>
    {
       var material2 = new THREE.MeshBasicMaterial( );
       var cube = new THREE.Mesh( geometry2, material2 );
       cube.material.map = texture;
       cube.position.set(0, -10, 0)
       scene.add( cube );
       face.material.map = texture;
       face.material.side = THREE.DoubleSide;

    }, undefined, undefined );

    
    console.log("Face", face)

    mesh.scale.set(10,10,10)
    mesh.position.x = 0;
    mesh.position.y = 0;
    mesh.position.z = 0;
    orbit.update();

    light.target = mesh;
  });

}

function onWindowResize() {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}

function render() {
  renderer.render(scene, camera);
}

function animate() {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
}

Face either has messed up UVs, unlit / broken / black material (diffuse map is multiplied by material color), or some other magic is happening - once again, hard to help you without a live example.

I took this example: Dodecahedron with a separate texture for each face
and changed it, so now the dodocahedron uses groups in its geometry, thus accepts an array of materials:
https://jsfiddle.net/prisoner849/eL75qgaf/

1 Like

Thank you, looks great! But I would like to figure out what is wrong with my dodecahedron.