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


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)

// 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);

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

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.

1 Like

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)

        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