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:
When creating fat lines instanced BufferAttributes are created for the start and end of each line (
instanceStart
andinstanceEnd
). You cannot usegeometry.attributes.position
to determine the number of colors needed for a segment. Instead you should useattributes.instanceStart.count
and use theLineSegmentsGeometry.setColors
function to ensure the correct instanced color attributes for each segment are set up.The LineMaterial color should be set to white so the vertex colors show when multiplied.
“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
andinstanceColorEnd
attributes and update them accordingly.
Here’s demo modified for your provided code showing how to accomplish this with some short inline comments: