Search Unity

Texturing Procedurally Generated Meshes

Discussion in 'Scripting' started by Velcrohead, Feb 14, 2015.

  1. Velcrohead

    Velcrohead

    Joined:
    Apr 26, 2014
    Posts:
    78
    Hi guys,
    I've been playing around attempting to procedurally generate some meshes to act as terrains, which is actually going rather well. However whilst creating these messages, I'm having to create triangles a bit irregularly, as I'd like to be able to deform the terrains by accessing their vertices.

    The triangles have been created making sure that they all share the vertices in the mesh, and each 'tile' (2 triangles next to each other making a square) doesn't use it's own individual 4 vertices (I hope this is still making sense!).

    The issue being, I've been trying to texture the mesh using UV mapping, utilising a tileSheet of smaller textures. The first 'tile' is textured correctly, however the following ones all use the texture next to the selected one on the tileSheet, and I'm really not quite sure why. Example :


    (It's supposed to be green all the way down).

    I'm not particularly familiar with UV mapping and so this has been a bit of a struggle. However, I am very open to any alternative methods of texturing my meshes.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,689
    In Unity's MeshFilter, the .vertices array and the .uv array are "in sync," along with the .normals array as well. That is, if you share a vertex, you also share the UVs for it.

    If you want to do tiling on a grid, you would need to add extra double verts in order to "restart" the UV coords for the next tile over at a different point in the grid.
     
  3. Velcrohead

    Velcrohead

    Joined:
    Apr 26, 2014
    Posts:
    78
    .Okay, thank you!

    I'm gonna give that a go as soon as Unity starts working again. As I am only creating 2 verts at a time, and then 2 UVs, wouldn't they be in sync anyway? (Example; adds 2 verts adding to the X axis, and uses the 2 previous verts used for the other side to create the total of 4).
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,689
    At any given vertex, if that vert position is shared between faces and yet is supposed to map to a discontinuity in your texture (say, go from 0.2 and jump to 0.5), then you will need to duplicate the vert position with a new UV, and use the correct one in each face that needs it.
     
  5. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,689
    Also, that darkening you see is probably the normals. For procedural meshing, I've not ever worried about normals and instead just called the .RecalculateNormals() function on the mesh when I am all done. If you share verts, it will smooth the normals across. If you have split verts (one for each face), then you will get a hard facet.
     
  6. Velcrohead

    Velcrohead

    Joined:
    Apr 26, 2014
    Posts:
    78
    Okay I see what you mean.

    I've been playing around with it this morning generating 4 vertices per face - however, when I try and raise a vertice up, it's leaving a hole in the mesh - this is because the other triangles aren't using the same vertex, and have a different height value, right?

    Is there any way to have 4 individual vertices, and not leave holes in the mesh when the height value is changed?
     
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,689
    Probably the cleanest way to do this would be to leave your original mesh design unchanged, but introduce an intermediary step from the vertices that are shared between triangles, to the actual ones shoveled into the mesh, and during that step introduce unique vertices per face. It's one extra pass through the verts whenever they get changed, but depending on your vert count, shouldn't be too bad.
     
  8. bloomingdedalus

    bloomingdedalus

    Joined:
    Aug 13, 2012
    Posts:
    139
    Like he said, the best way is to assemble your "theoretical" mesh in a class object where the vertices are shared and then duplicate all the vertices as you put them into the arrays you'll pass to the mesh renderer. You will have to hand calculate the normals (and tangents if you use normal mapping) for this method - but it's very doable...

    Here's procedurally generated terrain (a photo from another thread talking about some shader problems I had) I did with that method. The "theoretical" mesh all shares the same vertices, but when they're passed to the mesh renderer, each one is duplicated according to the number of faces per vertex: http://i.imgur.com/DP5vraQ.jpg

    Here's my final assembling routine that creates the arrays to pass to the mesh renderer as an example of what you need to do:

    Code (csharp):
    1.  
    2. public void AssembleMeshOutputArray()
    3.   {
    4.       OutVerts.Clear();
    5.       OutFaces.Clear();
    6.       OutNormals.Clear();
    7.   for (int i = 1; i < 33; i++)
    8.   {
    9.       for (int j = 1; j < 33; j++)
    10.       {
    11.            OutVerts.AddRange(new Vector3[] { Vec(i, j), Vec(i , j+1), Vec(i + 1, j + 1) });
    12.            OutUVs.AddRange(new Vector2[]{ StaticArrays.Mesh32UVs[i-1,j-1], StaticArrays.Mesh32UVs[i-1, j], StaticArrays.Mesh32UVs[i,j]});
    13.            OutVerts.AddRange(new Vector3[] { Vec(i, j), Vec(i + 1, j + 1), Vec(i+ 1, j ) });
    14.            OutUVs.AddRange(new Vector2[]{ StaticArrays.Mesh32UVs[i-1, j-1], StaticArrays.Mesh32UVs[i,j], StaticArrays.Mesh32UVs[i,j-1] });
    15.             for (int k = 0; k < 6; k++)
    16.             {
    17.                 OutFaces.Add(OutFaces.Count);
    18.             }
    19.            OutNormals.AddRange(new Vector3[] { Norm(i, j), Norm(i , j+1), Norm(i + 1, j + 1) });
    20.            OutNormals.AddRange(new Vector3[] { Norm(i, j), Norm(i + 1, j + 1), Norm(i+1, j ) });
    21.            OutTans.AddRange(new Vector4[] { Tan (i,j), Tan(i, j+1), Tan(i+1, j+1)});
    22.            OutTans.AddRange(new Vector4[] {Tan(i,j), Tan(i+1, j+1), Tan(i+1, j) });
    23.       }
    24.  }
    25. }
    26.  
     
    Last edited: Feb 16, 2015