Hi, I have a simple cube.fbx models with no texture that I load in my script. Is there a way to apply a texture to it? And then a way to select a specific face and apply another texture to it?
You can only apply a texture if your model has texture coordinates. Is this true for cube.fbx
?
That only works if you define group data for your geometry. That means you have to know the exact face indices or vertices. In most cases, it’s easier to define multiple materials for your asset in a DCC tool like Blender.
/cc
How can i check if my model has texture coordinates?
You have to check if the geometry of your meshes have a uv
buffer attribute. Put this code into your onLoad()
callback:
object.traverse( function ( child ) {
if ( child.isMesh ) {
console.log( child.geometry.attributes.uv );
child.material.map = texture; // assign your diffuse texture here
}
} );
Console says “undefined” as a result
How can i change uv buffer attribute in order to apply texture?
Well, you have to define an appropriate set of texture coordinates and apply them to the geometry. Something like:
const uvs = [0, 0, 0.5, 1, 1, 1 ...];
geometry.setAttribute( 'uv', new THREE.Float32BufferAttribute( uvs, 2 ) );
However, it’s complex to define proper texture coordinates for complex models like that. It’s better to import the FBX file into a DCC tool like Blender, author texture coordinates and then export the model again.
Is it possible to enable texture coordinates with photoshop too?
Sorry, I don’t know that. But since Photoshop is primarily a raster graphics editor, I don’t think it’s a good choice for that task (even if it has some 3D features).
Ok I’ve found another 3D models (with the win10 3d visualizer i can see that “Set UV” is enabled) , and when i run the script, in console i get “Float32BufferAttribute” (console.log( child.geometry.attributes.uv );). So i guess i can apply a texture to this model with the previous code you sent me, right?
Give it a try^^.
Ok it works, thanks a lot. Returning to my second question, i want to allow the user to select a face and change its texture, BufferGeometry class can help me?
Well, not really. Assuming you use THREE.Raycaster
to implement the interaction, intersection objects will contain face data. Check out the documentation of Raycaster.intersectObject() for more information.
As I mentioned before, you then need to author group data so you are able to assign multiple materials to your cube. I’m afraid this is actually advanced stuff and requires some knowledge about how BufferGeometry
works.
Unfortunately i’m not expert with this kind of stuff. But i want to give it a try. My idea is to decompose the problem in two:
- Highlight a face when the mouse goes over it;
- Select it by clicking;
- Change the texture;
For the first point do you suggest to focus on Raycaster ?
Yes. Studying how webgl_interactive_cubes works might be a good starting point.
I’ve found this old example of clicking on a gltf model. Are there any updated working example? I tried this and i cannot use “PMREMCubeUVPacker.js” file because i think it was used in older version of three and now it doesn’t exist anymore.
Updated the code to the latest version: https://jsfiddle.net/by5twLnr/2/
Thanks for sharing this great information. Could you share how to add multiple textures if you have multiple texture images?