Issue with Updating Face Color and Position on Click for Indexed Geometry in Three.js

Hi,

I’m working on a project in Three.js where I need to update the face color and position on click(using raycaster). I’ve created a basic shape using the IcosahedronGeometry and merged the vertices to achive indexed geometry. However, I’m encountering a problem where the mesh is not fully connected, resulting in a visible “rip” or seam.

const geometry = BufferGeometryUtils.mergeVertices(
  new THREE.IcosahedronGeometry(9, 3)
);
geometry.computeVertexNormals();

// Adding color attribute
const colors = [];
for (let i = 0; i < geometry.attributes.position.count; i++) {
  colors.push(1, 0, 0);
}
geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));

// Create mesh with material supporting vertex colors
const material = new THREE.MeshStandardMaterial({ vertexColors: true });
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

The way I am updating attributes is the following:

const geometry = intersection.object.geometry
const colors = geometry.getAttribute('color')
const positions = geometry.getAttribute('position')

const { face } = intersection
const { a, b, c, normal } = face

let color = new Color()
color.setRGB(0, 1, 0).convertSRGBToLinear()

  colors.setXYZ(a, 0, 1, 0)
  colors.setXYZ(b, 0, 1, 0)
  colors.setXYZ(c, 0, 1, 0)

 const vertices = [a, b, c]
 const displacement = 0.1

vertices.forEach((vertexIndex) => {
    const x = positions.getX(vertexIndex) + normal.x * displacement
    const y = positions.getY(vertexIndex) + normal.y * displacement
    const z = positions.getZ(vertexIndex) + normal.z * displacement

    positions.setXYZ(vertexIndex, x, y, z)
  })

positions.needsUpdate = true
colors.needsUpdate = true
geometry.computeVertexNormals()

Despite merging vertices, the mesh still appears to have a seam or “rip” when I update the face position and color. The vertices don’t seem to be fully connected.
Screenshots that visualise problem:



Any guidance or suggestions would be greatly appreciated. Thanks!

Before merging vertices, I would suggest first deleting any vertex attributes you don’t intend to use. Normals and UVs in particular. Differences in any vertex attribute can prevent vertices from being merged.

Thank you so much! Now it works :blush:
What about the case when I initialy have some faces in other color and want to apply the same attribute modyfications? How can I handle such scenario?
For example:


      const colors = []

      for (let i = 0; i < geometry.attributes.position.count; i++)
        Math.random() > 0.75 ? colors.push(1, 0, 0) : colors.push(0, 1, 0)

      geometry.setAttribute(
        'color',
        new THREE.BufferAttribute(new Float32Array(colors), 3)
      )

Would be very grateful for your advice :slightly_smiling_face:

Found solution! I need to merge vertices and then add color attribute