I had my first contacts with Three.js recently and I need some help to do some tests.
At the moment I am trying to create an AR application, where an object is inserted into the real environment using the cell phone’s camera. Initially the object is presented on the screen in blue color, however in the top I want to put three buttons with three different colors, for example blue, red and green, and when touching one of the buttons the object just change its colors.
I created the object and its materials on Blender. One of the faces of the object has a material with a UV texture and the rest of the object has a second material, without textures, just a material with the initial node (created in the Blender cycles). So I’ve created 6 materials, 3 for the textures, one each, and 3 for the colors, one each as well. On Blender I exported this object as .glb with materials and textures.
Now I’m importing this object on Three.js, I already understood how to add this object to the scene and render it so that it appears on the phone’s screen. Inclusive the first materials that came with the object worked normally (coming from .glb), I didn’t create anything about the materials in Three.js, everything is shown in the scene so far comes from the .glb that I exported in blender and just loaded on three.js.
Now I need to create the second part of the application, that is: when I touch the button of one color, the object must change color, as well as the “texture”. And it is here that I need help.
How do I do this? Do I need three different objects? Or just one object with all 6 materials? How can I do this features on three.js? I need help on Blender and on Three.js.
Can someone give a direction please? Or a link to a video or a good conversation about this theme.
Thanks in advance.
Essentially what you need to do is change the material of the relevant meshes within your .glb file.
When you load the .glb file with the GLTFLoader you give it an 'onLoad' function parameter where you have the first access to the contents of the file (the file itself is it's own mini scene) - This is the point where you can traverse through the scene, locate the mesh and save it as a variable so that you can later manipulate it.
Now, assuming there are more than a couple of meshes in the file, how can you know which one is correct? The best way would be by the name. Since you created the object from Blender, you can give a unique name to each mesh to later identify in three.js.
So now within the onLoad function you can insert some logic to confirm that the correct mesh is the one you are storing as a variable, consider the following code:
let meshFromGLTF;
const meshName = "MESH_0" // assuming this is the name you gave it on blender
...
loader = new GLTFLoader();
loader.load( "path/to/gltf", ( gltf ) => {
const scene = gltf.scene;
scene.traverse( ( child ) => {
if ( child.isMesh && child.name === meshName ) { // to confirm it is a mesh
meshFromGLTF = child;
// this may also be a good point to store the original material as a variable
}
}
})
And now since you stored the mesh as a variable, it will be easy to change it's material and texture with a button. Simply supply an onClick function when the button is clicked and within that function you can do the following:
const texture = textureLoader.load( 'path/to/texture.png' );
const materialBlue = new MeshBasicMaterial ( { map: texture, color: 'blue' } );
function onClickBlue () {
meshFromGLTF.material = materialBlue;
}
In terms of creating materials for the mesh, it is quite a broad topic, you can check out the documentation and see what kind of materials you may need, textures you apply on the material itself on parameters that include the word 'map'.
I created a small example here that does this approach.