Skip to content
Advertisement

three.js Highlighting the edge of a cube on hover LineSegmentsGeometry

I am using LineSegmentsGeometry and LineMaterial to create thick cube edges. I want to change the color of the edge on hover.

const edgesGeometry = new LineSegmentsGeometry().fromEdgesGeometry(
  new THREE.EdgesGeometry(mesh.geometry, 40)
);
const colors = [];
for (let i = 0; i < edgesGeometry.attributes.position.count; i++) {
  colors.push(0, 0, 0);
}
edgesGeometry.setAttribute(
  "color",
  new THREE.Float32BufferAttribute(colors, 3)
);
const edgesMaterial = new LineMaterial({
  color: "black",
  vertexColors: true,
  linewidth: 0.001
});
const line = new THREE.LineSegments(edgesGeometry, edgesMaterial);
const setLineColor = (color) => {
  const { index, object } = intersected;
  object.geometry.attributes.color.setXYZ(index, color.r, color.g, color.b);
  object.geometry.attributes.color.setXYZ(index + 1, color.r, color.g, color.b);
  object.geometry.attributes.color.needsUpdate = true;
};

This code only works if using thin lines with LineBasicMaterial. Can I do it somehow with bold lines? I also have other shapes with this logic sandbox here https://codesandbox

Advertisement

Answer

You can do it with fat lines! LineSegmentsGeometry (fat lines) is structured quite a bit differently from EdgesGeometry, though, so the approach must be updated.

Looking at your example there are a few things to note:

  1. When creating fat lines instanced BufferAttributes are created for the start and end of each line (instanceStart and instanceEnd). You cannot use geometry.attributes.position to determine the number of colors needed for a segment. Instead you should use attributes.instanceStart.count and use the LineSegmentsGeometry.setColors function to ensure the correct instanced color attributes for each segment are set up.

  2. The LineMaterial color should be set to white so the vertex colors show when multiplied.

  3. “index” is not provided when intersecting with fat lines. Instead you should use “faceIndex” and use that to set the color fields on the instanceColorStart and instanceColorEnd attributes and update them accordingly.

Here’s demo modified for your provided code showing how to accomplish this with some short inline comments:

https://jsfiddle.net/juoz5yLv/1/

Advertisement