How do I fix my UV's of a generated Mesh?

Hey,

I’ve generated this plane mesh right here with some grid positions. Each grid Vector2 positions generates one quad.

 private Mesh GenerateMeshFromTiles(List<Tile> tiles)
    {
        Mesh mesh = new Mesh();
        Vector3[] vertices;

        // Calculate the 4 Vertices of one Tile
        List<Vector3> tileVertices = new List<Vector3>();
        vertices = new Vector3[(tiles.Count * 3 + 1) * (tiles.Count * 3 + 1)];

        for (int i = 0; i < tiles.Count; i++)
        {
            // -x Going left, +x going right
            // -z going bot , +z going top

           Tile tile = tiles[i];

            // Calculate the 4 Positions from 1 Point
            var xPos0 = tile.X - 0.5f;
            var yPos0 = 0.02f;
            var zPos0 = tile.Y - 0.5f;

            var xPos1 = tile.X + 0.5f;
            var yPos1 = 0.02f;
            var zPos1 = tile.Y - 0.5f;

            var xPos2 = tile.X - 0.5f;
            var yPos2 = 0.02f;
            var zPos2 = tile.Y + 0.5f;

            tileVertices.Add(new Vector3(xPos0, yPos0, zPos0));
            tileVertices.Add(new Vector3(xPos1, yPos1, zPos1));
            tileVertices.Add(new Vector3(xPos2, yPos2, zPos2));

            var xPos5 = tile.X + 0.5f;
            var yPos5 = 0.02f;
            var zPos5 = tile.Y + 0.5f;

            tileVertices.Add(new Vector3(xPos5, yPos5, zPos5));
        }

        vertices = tileVertices.ToArray();
        mesh.vertices = vertices;

        // Create triangles
        int[] triangles = new int[tiles.Count * 2 * 3];
        int n = 0;
        for (int i = 0; i < triangles.Length / 6; i++)
        {
            triangles[i * 6 + 1] = 2 + n;
            triangles[i * 6 + 0] = 0 + n;
            triangles[i * 6 + 2] = 1 + n;

            triangles[i * 6 + 3] = 2 + n;
            triangles[i * 6 + 4] = 3 + n;
            triangles[i * 6 + 5] = 1 + n;
            n += 4;
        }
        mesh.triangles = triangles;

        //Calculate UV's
        //UV's
        Vector2[] uv = new Vector2[vertices.Length];
        for (int i = 0; i < mesh.vertices.Length; i++)
        {
            uv[i] = new Vector2(0, 0);
            uv[i + 1] = new Vector2(0, 1);
            uv[i + 2] = new Vector2(1, 1);
            uv[i + 3] = new Vector2(1, 0);
            i += 3;
        }
        mesh.uv = uv;
        //Normals
        mesh.RecalculateNormals();

        mesh.vertices = vertices;
        return mesh;
    }

The mesh seems to be correct but my UV’s are not. On the left side is a standard Unity Plane and on the right side is my generated mesh.

Anybody can figure out what I did wrong? Thanks in advance.

Unrelated, but delete this line:

 vertices = new Vector3[(tiles.Count * 3 + 1) * (tiles.Count * 3 + 1)];

You don’t need it because you’re populating vertices from the list later, and you’re allocating the wrong number of vertices anyway.

As for what you’re doing ‘wrong’, that depends on what you want to happen.

Currently, you’re setting the UVs of each tile to (0,0), (1,0), (0,1) and (1,1), which means each tile will display the entire texture. If you don’t want it to do that, you need to make each tile display the region of the texture that you want.

1 Like

If you don’t want to hassle with co-generating UVs, you can just analyze any arbitrary mesh and replace its UVs with triplanar coordinates. It gets you a long ways toward simple pattern repetition and may be suitable for at least demo needs. I have a handy script I always use:

It’s all pretty straightforward and you can copy / paste whatever parts you need or just use it as-is.

1 Like

Like @Peeling said you currently map every quad of your mesh to the entire texture. If that’s what you want, fine. If not you have to use fractional UV coordinates that match the desired position in the texture space.

However apart from that, the skewing you’re seeing comes from wrong UV to vertices mapping, When you create your vertices you create 4 vertices for each cell. You create then in this order

(-1,-1)
(+1,-1)
(-1,+1)
(+1,+1)

This is what you do line 18 to 38. However when creating the UVs in line 65 to 68 you create them in this order:

(0, 0)
(0, 1)
(1, 1)
(1, 0)

So your vertex and uv layout looks like this:

// vertices            uvs
// 2-----3           1-----2
// | \   |           | \ / |
// |   \ |           | / \ |
// 0-----1           0-----3

// first triangle
// vertices            uvs
// 2                 1-----2
// | \               |   /
// |   \             | /
// 0-----1           0

// second triangle
// vertices            uvs
// 2-----3           1-----2
//   \   |             \   |
//     \ |               \ |
//       1                 3

Note that the numbers in the corners are the indices. However you have to imagine to map the “UV” triangle onto the actual triangle so that the indices match. As you can see, you’re doing a strange diagonal flip as well as a skew.

Furthermore triangles have to be either clockwise in order to be rendered correctly unless you have a double sided shader. Your first triangle is defined as 2, 0, 1 which has a counter clockwise winding while the second one 2,3,1 has a clockwise winding order when viewed from above. So this doesn’t make much sense. You really should take pen and paper and draw a single quad and write down what values you expect in order to setup the mesh correctly.

Since you showed the plane mesh as reference, does tnat mean you want to map your different tiles to the different corresponding areas of the texture? If that’s the case, you can not use 0 and 1 as UV coordinates since those denote the corners of the texture. So you would map the whole texture to each tile. You have overcomplicated the whole generation quite a bit. We don’t know where your tiles come from and what Tile actually is (it’s most likely not Unity’s Tile class). So we don’t know in what ranges your tile.X and tile.Y values are defined in. We can assume that they increase by 1, but they could start at 0 or any other kind of value like “-1.5” for example so the origin would be in the center rather than the bottom left corner. You have to know the range of the tile position in order to calculate proper UV coordinates.

1 Like