2

I am coding a procedural asteroid generator in Unity using a custom mesh.

The main idea is taken from this YouTube series, where you basically create your own cube with six evenly sub-divided sites, then normalize the vertices and apply a noise function. So far so good.

The problem appears to be a visible seam at the edges of the cube. Here is a screenshot:

The visible seams between the faces

I already figured out, that this comes from a bad normals calculation because normals can not be calculated properly for edge vertices.
I tried to solve this by just making my original mesh two vertices bigger in each dimension, then running the RecalculateNormals function on this mesh, and then trying to get rid of the added triangles at the fringe.

You can find my code for generating one of the 6 sides below:

Vector3[] vertices = new Vector3[(resolution + 2) * (resolution + 2)]; // We need a rim for correct normal generation!
int[] allTriangles = new int[(resolution - 1 + 2) * (resolution - 1 + 2) * 6]; // Mind the rim!
int[] filteredTriangles = new int[(resolution - 1) * (resolution - 1) * 6]; // Only the visible triangles
int triIndexAllTriangles = 0;
int triIndexFilteredTriangles = 0;

for (int y = -1; y < resolution + 1; y++) // We iterate over all (visible and invisible) vertices
{
    for (int x = -1; x < resolution + 1; x++)
    {
        int i = (x + 1) + ((y + 1) * (resolution + 2)); // Calculate the current vertex index
        Vector2 percent = new Vector2(x, y) / (resolution - 1); // We will work with a relative width of the grid
        Vector3 pointOnUnitCube = localUp + (percent.x - 0.5f) * 2 * axisA + (percent.y - 0.5f) * 2 * axisB; // Calculate the position of the point on the cube (the point is relative to a local upwards facing axis)
        Vector3 pointOnUnitSphere = pointOnUnitCube.normalized; // Make a sphere
        vertices[i] = shapeGenerator.CalculatePointOnPlanet(pointOnUnitSphere); // Calculate the height of the point with some noise function
                
        ///// Face Generation /////
        if (x != resolution - 1 + 1 && y != resolution - 1 + 1) // Do not calculate a face for the righmost or upmost row of vertices
        {
            if (!(x == -1 || x == resolution - 1 || y == -1 || y == resolution - 1)) // Filtered ("visible") triangles will be stored in a separate triangle buffer
            {
                filteredTriangles[triIndexFilteredTriangles] = i;
                filteredTriangles[triIndexFilteredTriangles+1] = i+resolution+1 + 2;
                filteredTriangles[triIndexFilteredTriangles+2] = i+resolution + 2;

                filteredTriangles[triIndexFilteredTriangles+3] = i;
                filteredTriangles[triIndexFilteredTriangles+4] = i+1;
                filteredTriangles[triIndexFilteredTriangles+5] = i+resolution+1 + 2;

                triIndexFilteredTriangles += 6;
            }

            allTriangles[triIndexAllTriangles] = i;
            allTriangles[triIndexAllTriangles+1] = i+resolution+1 + 2;
            allTriangles[triIndexAllTriangles+2] = i+resolution + 2;

            allTriangles[triIndexAllTriangles+3] = i;
            allTriangles[triIndexAllTriangles+4] = i+1;
            allTriangles[triIndexAllTriangles+5] = i+resolution+1 + 2;

            triIndexAllTriangles += 6;
        }
    }
}

// First store the vertices, then all (visible and invisible) triangles. Calculate the normals with all vertices and then overwrite the triangles with only the visible triangles
mesh.Clear();
mesh.vertices = vertices;
mesh.triangles = allTriangles;
mesh.RecalculateNormals();
mesh.triangles = filteredTriangles;

I am not sure if this is the right way to overwrite faces in a mesh. But as a matter of fact, this code still shows visible seams and I am not sure what I do wrong here.

All help is greatly appreciated.

0 Answers0