Hi There.
I exported an object from Blender to a gltf-file and imported it into my three.js project. (Including materials, ive got 2 in total)
let loader = new THREE.GLTFLoader();
loader.load('Objects/MyBox.gltf', (gltf) => {
let box = gltf.scene;
box.traverse((child) => {
if (child.isMesh) child.material = boxMaterial; // a material i created in the code earlier
});
scene.add(box);
});
This code causes my imported Object (which is a folded box) to have the same material (boxMaterial) on the outside and on the inside.
But as i created it in bleder ( inside of the box has an inside material, the outside has an outside material) i want it to be in my three.js project. What I want is = the boxMaterial(created in three.js) shall only be on the outside-Material(created in blender).
My question is -> how do I tell/access the specific imported material of my imported object to have a certain material in three.js?
in easier words: “child.material” contains my needed materials.(2 in total) But how do I get/access only the first one?
I think I’m looking for something like a box.children[0].material… or something. the index 0 has my outside material.
Blockquote
TBH, I’m not sure I understand your question.
Well, I imported a gltf-file including the materials I need. (When I exported my object from Blender they got included because I gave the Object materials in the first place → InsideBox, OutsideBox)
When I traversed them (as you can see in my code) I only knew about the option to apply my material (boxMaterial → which I created in three.js) on to the child.material.
But since “child.material” includes my imported materials “InsideBox” AND “OutsideBox” → the WHOLE box gets the boxMaterial (In my code: child.material = boxMaterial) even though it should only be on the “OutsideBox”-Material.
So my goal is to access the imported “OutsideBox”-Material, so I can ONLY apply the boxMaterial(which i created in three.js) to the “OutsideBox”-Material but NOT to the “InsideBox”-Material.
Blockquote
However, you should be able to retrieve all materials of a glTF asset with this code:
It is hard for us to know what is in your glTF file without inspecting it. Perhaps try viewing it in https://gltf-viewer.donmccurdy.com/, open the JS Console, and take a screenshot of the output? Something like this, for example:
If your model had 2 materials and 1 mesh in Blender, I would expect that there are 2 materials and 2 meshes in three.js. We do not import a single mesh with multiple materials.
However, you should be able to retrieve all materials of a glTF asset with this code:
Note that this will give you every material in the original glTF file. That has its uses, but does not necessarily give you every material in the final scene. This is because the loader may need to make copies of some materials, in order to have versions with/without skinning, vertex colors, and so on. If you need to modify the materials that are already applied to your meshes, it’s better to traverse the scene and modify things there.
For anybody still struggling with this, here’s a code snippet that worked for me. Recurses through all the GLTF’s children, and replaces each material with a new one that has the same texture.
setMaterialsOnGLTF(object3D) {
if (object3D.material) {
const newMaterial = new THREE.MeshPhongMaterial( { map: object3D.material.map } );
object3D.material = newMaterial;
}
if (!object3D.children) {
return;
}
for (let i = 0; i < object3D.children.length; i++) {
Utilities.setMaterialsOnGLTF(object3D.children[i]);
}
}
And if you’re using a GLTF, you’ll want to pass in gltf.scene from the loader.