Dawid Zbiński
Dawid Zbiński

Reputation: 5826

Set material to a fixed part of mesh in Three.js

Let's say I have a 3DObject in three.js:

const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshStandardMaterial({ color: 0xff0000 });
const mesh = new THREE.Mesh(geometry, material);

This mesh is also dynamic, that means, user sets the size of it, which is dynamically set as the scale of the mesh.

widthInput.subscribe(value => this.mesh.scale.x = +value); // just to get the idea

So, I know it's possible to set separate materials to the different sides of geometry. I'm also aware that it should be possible to set it on separate segments of that geometry's sides (if I'd had more).

The problem is that the user can set the width from the range 200 - 260, but I need a different material on the very right of the mesh with a fixed size of 10. I'm not really sure how would I do that without creating another geometry. Is there any way to set the material on the fixed part of the mesh? or is there any way to set the segments the way one of them will always have the fixed size? Thank you in advance.

To visualize the problem (white area needs to have a fixed width of 10 while the red area resizes)

enter image description here

Upvotes: 1

Views: 546

Answers (1)

pailhead
pailhead

Reputation: 5431

Is there any way to set the material on the fixed part of the mesh?

As you've already mentioned there is a way to set different materials on different parts of the geometry. The problem here is defining what fixed means:

or is there any way to set the segments the way one of them will always have the fixed size?

Yes. You'd have to modify the geometry yourself. Reach into say g.attributes.position.array and modify the vertices that make the segment. It's lower level and different than the scene graph.

There may not be a good reason for wanting to keep everything in the same geometry. It would make sense if you used vertex colors for example to paint the different segments, and perhaps animated the extrusion in GLSL rather than with scale.set(). But since you want to apply different materials and are not writing GLSL, you will end up with multiple draw calls anyway.

You actually can save a bit of memory by storing just the simple cube and referencing it twice, than storing extra vertices and faces. So what you're trying to do is more likely going to consume more memory, and have the same amount of render overhead. In which case, doing everything with the scene graph, with two meshes and one geometry (you dont need to duplicate the box, you only need two nodes) should be as performant, and much easier to work with.

Upvotes: 2

Related Questions