How to smoothen Mesh created with VertexData

I have a mesh with UV map resembling a face and updating vertex data positions as needed - and this works perfectly

Question is how would you make this look “smoother” (e.g. increase number of indices)

I’ve looked at increaseVertices method, but then the new number of vertices will not match updated data (Invalid typed array length in Geometry.getVerticesData)

// create once
const mesh = new Mesh('face', scene);
const vertexData = new VertexData();
vertexData.positions = positions; // updated data
vertexData.indices = faceTriangulation; // predefined
vertexData.uvs = faceUVMap.flat(); // predefined
vertexData.applyToMesh(mesh, true);

// runs in update loop
mesh.setVerticesData(VertexBuffer.PositionKind, positions, true);

(idea with increasing number of indices is just an idea, I’m open to any other approach as well)

Example output:

There is another reason increasedVertices will not work for you. For a given facet the extra vertices will still lie in the plane of the facet and so will not add any curvature.

Out of interest try forceSharedVertices

and see if you get smoother results.

1 Like

good point on increasedVertices

anyhow, i cannot get any of the methods to work: increaseVertices(), forceSharedVertices(), convertToFlatShadedMesh() - they all result in the same error: Invalid typed array length in Geometry.getVerticesData

just toying around, only method that does work is convertToUnIndexedMesh which results in hilarious output:

Would it be possible to import your face mesh into a playground?

I wonder if there is something in the construction of the face that does not match the expected mapping of facet, vertices, indices by the applied functions?

I wonder if there is something in the construction of the face that does not match the expected mapping of facet, vertices, indices by the applied functions?

Ahhh, yesss - positions array had few extra points (eye iris definitions) which were not accounted for in uvs.
Everything works even with mismatch until I try to apply a method like forceSharedVertices and then if errors out.

Removed the extra points and now after applying forceSharedVertices it looks exactly like i wanted!

But…How do I update positions now?

Calling mesh.setVerticesData(VertexBuffer.PositionKind, positions, true)
in a loop after forceSharedVertices has been called results in error as vertex count no longer matches.

Without seeing your code it is impossible to see how you are handling things. At a guess use

smooth = mesh.forceSharedVertices()

Then read positions from smooth and then update smooth in your loop.

Sorry but will not now be available for a day or two.

From what I can see, mesh.forceSharedVertices() sometimes (not always) changes number of indices - mesh.getTotalVertices() returns smaller number than original.

Which means calling mesh.updateVerticesData(VertexBuffer.PositionKind, positions) after vertices size gets reduced will result in error as array sizes do not match.

Ok, I think I got it - instead of using mesh.forceSharedVertices() which may change number of vertices and cause problems, I can get same effect by manually calculating normals when creating initial VertexData

    vertexData= new VertexData();
    vertexData.positions = positions;
    vertexData.indices = faceTriangulation;
    vertexData.uvs = faceUVMap.flat();
    if (smooth) {
      const normals: number[] = [];
      VertexData.ComputeNormals(positions, faceTriangulation, normals);
      vertexData.normals = normals;
    } else {
      vertexData.normals = null;
    }
    vertexData.applyToMesh(mesh, true);

And with this approach, there are no issues with subsequent updates using mesh.updateVerticesData(...)