Search code examples
c#unity-game-enginemeshterrainprocedural-generation

Terrain having visible seams at vertices - How can i fix this?


i'm a newbie and i am following a tutorial on procedural landmass generation. However, my plane does not look right. It has a lot of seams/cracks. Is there someone who can point me in the right direction?

Procedural Generated Terrain

Below is my MeshGenerator scripts:

public static class MeshGenerator
{
    public static MeshData GenerateTerrainMesh(float[,] heightMap, float heightMultiplier, AnimationCurve heightCurve)
    {
        int width = heightMap.GetLength(0);
        int height = heightMap.GetLength(1);
        float topLeftX = (width - 1) / -2f;
        float topLeftZ = (height - 1) / 2f;

        MeshData meshData = new MeshData(width, height);
        int vertexIndex = 0;
        
        for (int y = 0; y < height; y++)
        {
            for (int x = 0; x < width; x++)
            {
                meshData.vertices[vertexIndex] = new Vector3(topLeftX + x, heightCurve.Evaluate(heightMap[x,y]) * heightMultiplier, topLeftZ - y);
                meshData.uvs[vertexIndex] = new Vector2(x / (float)width, y / (float)height);
                
                if (x < width - 1 && y < height - 1)
                {
                    meshData.AddTriangle(vertexIndex, vertexIndex + width + 1, vertexIndex + width);
                    meshData.AddTriangle(vertexIndex, + width + 1, vertexIndex + 1);
                }

                vertexIndex++;
            }
        }
        return meshData;
    }
}

public class MeshData
{
    public Vector3[] vertices;
    public int[] triangles;
    public Vector2[] uvs;

    int triangleIndex;

    public MeshData(int meshWidth, int meshHeight)
    {
        vertices = new Vector3[meshWidth * meshHeight];
        uvs = new Vector2[meshWidth * meshHeight];
        triangles = new int[(meshWidth-1) * (meshHeight-1)*6];
    }

    public void AddTriangle(int a, int b, int c)
    {
        triangles[triangleIndex] = a;
        triangles[triangleIndex+1] = b;
        triangles[triangleIndex+2] = c;
        triangleIndex += 3;
    }
    public Mesh CreateMesh()
    {
        Mesh mesh = new Mesh();
        mesh.vertices = vertices;
        mesh.triangles = triangles;
        mesh.uv = uvs;
        mesh.RecalculateNormals();
        return mesh;
    }
}

Solution

  • You triangle indices are wrong, this is rather obvious since you have a bunch of triangle-shaped holes. Notably

    meshData.AddTriangle(vertexIndex, + width + 1, vertexIndex + 1);

    the second vertex of the second triangle is a constant value, and that is most likely incorrect

    You should not need to keep a running total of vertexIndex, you should be perfectly able to compute the triangle indices from the grid indices:

    var v1 = y * (width+1) + x; // You should have one more column of vertices than you have grid cells
    var v2 = v2 + 1;  // the vertex one column to the right
    var v3 = v1 + width+1; // the vertex one row down
    var v4 = v3 + 1;
    
    meshData.AddTriangle(v1, v2, v4);
    meshData.AddTriangle(v1, v4, v3);
    

    You may need to invert the vertex order to ensure the normals are oriented correctly.