Custom generated mesh - How to set UV correctly [Fied]

[EDIT: First problem solved! ]

I’ve created a little function the generate a 16x16 chunk of a noise. After setting up the vertices and triangle, I had to do the normals, but “mesh.RecalculateNormals()” was smoothing out the terrain instead of making it flat. I had to use a technique (which is maybe the cause of the problem) that rearange triangles and vertices to flatten the mesh. (See this thread Custom voxel-like generated mesh dosen't have good normals. - Unity Engine - Unity Discussions for more information).

When I started working on the UVs for my mesh, [FIX] the texture wasn’t applied correctly, [NEED HELP] the quad on the wall were stretching the texture instead of reapeating it and I didn’t know how to apply [Almost FIX] custom texture for each block, I was obligated to use only one texture for the whole chunk.

  • Here we can see my 2nd problem

    Note: The texture is streached (the pixel are squashed instead of 1:1 pixel), what I want Is a texture that start from the top and reapet until it reach the bottom of the quad.
    EDIT: I would also like to have a repeated texture that has a top part that repeat once and a bottom part that repeat, like this:

CODE:
```csharp
** GameObject cChunk = (GameObject)Instantiate(MeshTemplate,new Vector3(TestStartPos.xSimulatedChunkSize,0,TestStartPos.ySimulatedChunkSize),Quaternion.identity);
Mesh cMesh = new Mesh();
List Vertices = new List();
List Triangles = new List();
List UVs = new List();

    for(int y = 0; y < SimulatedChunkSize; y++) {
        for(int x = 0; x < SimulatedChunkSize; x++) {
            int c = ((x+y*r)*4);

            Vertices.Add(new Vector3(x,GetValueAtPixel(x+(TestStartPos.x*SimulatedChunkSize),y+(TestStartPos.y*SimulatedChunkSize)),y));
            Vertices.Add(new Vector3(x+1,GetValueAtPixel(x+(TestStartPos.x*SimulatedChunkSize),y+(TestStartPos.y*SimulatedChunkSize)),y));
            Vertices.Add(new Vector3(x,GetValueAtPixel(x+(TestStartPos.x*SimulatedChunkSize),y+(TestStartPos.y*SimulatedChunkSize)),y+1));
            Vertices.Add(new Vector3(x+1,GetValueAtPixel(x+(TestStartPos.x*SimulatedChunkSize),y+(TestStartPos.y*SimulatedChunkSize)),y+1));

            Triangles.Add(c+1);
            Triangles.Add(c+0);
            Triangles.Add(c+2);

            Triangles.Add(c+1);
            Triangles.Add(c+2);
            Triangles.Add(c+3);

            Vector2 tempUV0 = PixelToUV(0,0);
            Vector2 tempUV1 = PixelToUV(16,16);

            UVs.Add(new Vector2(tempUV0.x,tempUV0.y));
            UVs.Add(new Vector2(tempUV1.x,tempUV0.y));
            UVs.Add(new Vector2(tempUV0.x,tempUV1.y));
            UVs.Add(new Vector2(tempUV1.x,tempUV1.y));
        }
    }

    int v = Vertices.Count;

    for(int y = 0; y < SimulatedChunkSize; y++) {
        for(int x = 0; x < SimulatedChunkSize; x++) {

            int c = ((x+y*SimulatedChunkSize)*4);
            int c2 = v+c;

            float nX = GetValueAtPixel(x+(TestStartPos.x*SimulatedChunkSize)+1,y+(TestStartPos.y*SimulatedChunkSize));
            float nY = GetValueAtPixel(x+(TestStartPos.x*SimulatedChunkSize),y+(TestStartPos.y*SimulatedChunkSize));
            float nZ = GetValueAtPixel(x+(TestStartPos.x*SimulatedChunkSize),y+(TestStartPos.y*SimulatedChunkSize)+1);

            Vertices.Add(new Vector3(x+1,nX,y+1));
            Vertices.Add(new Vector3(x+1,nX,y));

            Vertices.Add(new Vector3(x+1,nZ,y+1));
            Vertices.Add(new Vector3(x,nZ,y+1));

            Vector2 tempUV0 = PixelToUV(0,0);
            Vector2 tempUV1 = PixelToUV(16,16);
            Vector2 tempUV2 = PixelToUV(0,0);
            Vector2 tempUV3 = PixelToUV(16,16);

            Triangles.Add(c+3);
            Triangles.Add(c2);
            Triangles.Add(c+1);

            Triangles.Add(c2);
            Triangles.Add(c2+1);
            Triangles.Add(c+1);

            UVs.Add(new Vector2(tempUV0.x,tempUV0.y));
            UVs.Add(new Vector2(tempUV1.x,tempUV0.y));
            UVs.Add(new Vector2(tempUV0.x,tempUV1.y));
            UVs.Add(new Vector2(tempUV1.x,tempUV1.y));

            Triangles.Add(c+2);
            Triangles.Add(c2+3);
            Triangles.Add(c+3);

            Triangles.Add(c2+3);
            Triangles.Add(c2+2);
            Triangles.Add(c+3);

            UVs.Add(new Vector2(tempUV2.x,tempUV2.y));
            UVs.Add(new Vector2(tempUV3.x,tempUV2.y));
            UVs.Add(new Vector2(tempUV2.x,tempUV3.y));
            UVs.Add(new Vector2(tempUV3.x,tempUV3.y));
        }
    }

    Vector3[] oldVerts = Vertices.ToArray();
    int[] triangles = Triangles.ToArray();
    Vector3[] vertices = new Vector3[triangles.Length];
    for (int i = 0; i < triangles.Length; i++) {
        vertices[i] = oldVerts[triangles[i]];
        triangles[i] = i;
    }

    Debug.Log(vertices.Length);
    Debug.Log(UVs.Count);

    for(int x = 0; x < (1536/4); x++) {
        Vector2 tempUV0 = PixelToUV(0,0);
        Vector2 tempUV1 = PixelToUV(16,16);

        UVs.Add(new Vector2(tempUV0.x,tempUV1.y));
        UVs.Add(new Vector2(tempUV1.x,tempUV1.y));
        UVs.Add(new Vector2(tempUV0.x,tempUV0.y));
        UVs.Add(new Vector2(tempUV1.x,tempUV0.y));
    }

    Debug.Log(vertices.Length);
    Debug.Log(UVs.Count);

    cMesh.SetVertices(vertices.ToList());
    cMesh.SetTriangles(triangles.ToList(),0);
    cMesh.SetUVs(0,UVs);

    cMesh.RecalculateBounds();
    cMesh.RecalculateNormals();

    cChunk.GetComponent<MeshFilter>().mesh = cMesh;
    cChunk.GetComponent<MeshCollider>().sharedMesh = cMesh;**

** **OTHER FUNCTIONS:** **csharp
** float GetValueAtPixel (float x, float y) {
return Mathf.PerlinNoise(xparameters.Frequency,yparameters.Frequency)*parameters.Amplitude;
}

Vector2 PixelToUV (int x, int y) {
    return new Vector2(x/512f,1-(y/512f)); //Size of texture: 512x512
}**

```

Edit: The function that rearange the order of the vertices is causing some problem because the vertecies aren’t in a group of 4 or 2 anymore, they all rearange based of the triangle used.

3147224--239078--UVMissplaced.png
3147224--239079--UVStreching.png
3147224--239423--RepeatUV.png

Still no answers.

Why does everyone ignore this thread?

Hi STUDIOCRAFTapps,

if you are rearranging the vertex positions you need to rearrange the UVs the same way, otherwise you end up having UVs that do not correspond to your vertex.

1 Like

Let me try that…

After rearrenging all the UVs, the floor tiles are now correct but the wall tile are not because the are sharing the same verticees; how to fix that? Duplicating some vertices?

3149984--239400--UVWall.png

Yep, this is the same problem as the vertex normals you were experiencing before, each vertex can only store one version of the main UVs, and you can’t UV map an entire box with shared vertex UVs as you’ll get the warping like you had on the top. Now that you’ve fixed the top the best you can get is some warping on the sides.

Alternatively you could look at using a triplanar shader and skip using UVs entirely.

1 Like

Thanks, my first UV problem is solved.

To achieve this you’ll need to have extra vertices, and manage the “repeat” part manually. Since, as bgolus mentioned, you can have only one UV set per vertex, you’d need to manually put vertices in places where you want to repeat the texture vertically. You’d also have to duplicate them, one vertex having 0 in v coordinate and another having the V coordinate that corresponds to the top of the part you want to repeat.

But that will cost a lot more triangle…

Yes, but the GPUs only support REPEAT mode for full textures, e.g. it’s just a way to treat UVs over 1.0
You could separate it into two textures (top non-repeating part and bottom repeating part) and save some triangles.

Good Idea but the problem is that I don’t want to separate my texture and using UVs over 1.0 won’t work on this texture unless I decide to divide it into multiple texture.

3151109--239505--Texture.png

I’ve used the expensive method, It work perfectly exept for some shadow bugs…

http://imgur.com/a/7WNrT

If you need to avoid so many triangles, you could add some code in shader to adjust (just calculate the mapping uv yourself)

Also my tool Mesh Visiualizer https://assetstore.unity.com/packages/tools/modeling/mesh-visualizer-113410 may help (with visualizing UV easily :smile:)

Sorry but that bug was fixed waaay long ago ^^