Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more..
    Dismiss Notice
  3. Dismiss Notice

How to generate normals and UVs for a procedurally generated mesh

Discussion in 'General Graphics' started by tomchambers, Feb 7, 2021.

  1. tomchambers

    tomchambers

    Joined:
    Mar 21, 2016
    Posts:
    19
    I have a mesh generation script that produces meshes that look like this:


    The problem is when I render them they turn out like this:


    I know I need to generative normals and UV coords for it, but I have no idea how to do that. All I want is for the object to have a solid color and for shadows/lighting to work correctly.

    This is what my mesh generation code looks like:
    Code (CSharp):
    1.     public void RenderMesh(List<Vector3> positions, int maxIterations, int layerResolution)
    2.     {
    3.         var triangles = new List<int>();
    4.         var meshFilter = gameObject.GetComponent<MeshFilter>();
    5.         var meshCollider = gameObject.GetComponent<MeshCollider>();
    6.         Mesh mesh = new Mesh();
    7.         meshFilter.mesh = mesh;
    8.  
    9.  
    10.         for (int level = 1; level <= maxIterations; level++)
    11.         {
    12.             if (level < maxIterations)
    13.             {
    14.                 for (int circlePoint = 0; circlePoint < layerResolution; circlePoint++)
    15.                 {
    16.                     var index = level * layerResolution + circlePoint;
    17.                     if (circlePoint < layerResolution - 1)
    18.                     {
    19.                         triangles.Add(index);
    20.                         triangles.Add(index - layerResolution + 1);
    21.                         triangles.Add(index - layerResolution);
    22.  
    23.                         triangles.Add(index);
    24.                         triangles.Add(index + 1);
    25.                         triangles.Add(index - layerResolution + 1);
    26.  
    27.                         triangles.Add(index - layerResolution);
    28.                         triangles.Add(index - layerResolution + 1);
    29.                         triangles.Add(index);
    30.  
    31.                         triangles.Add(index - layerResolution + 1);
    32.                         triangles.Add(index + 1);
    33.                         triangles.Add(index);
    34.                     }
    35.                     else
    36.                     {
    37.                         triangles.Add(index);
    38.                         triangles.Add(index - 2 * layerResolution + 1);
    39.                         triangles.Add(index - layerResolution);
    40.  
    41.                         triangles.Add(index - layerResolution + 1);
    42.                         triangles.Add(index - 2 * layerResolution + 1);
    43.                         triangles.Add(index);
    44.  
    45.                         triangles.Add(index - layerResolution);
    46.                         triangles.Add(index - 2 * layerResolution + 1);
    47.                         triangles.Add(index);
    48.  
    49.                         triangles.Add(index);
    50.                         triangles.Add(index - 2 * layerResolution + 1);
    51.                         triangles.Add(index - layerResolution + 1);
    52.                     }
    53.                 }
    54.             }
    55.             else
    56.             {
    57.                 var lastPointIndex = positions.Count - 1;
    58.                 for (int circlePoint = 0; circlePoint < layerResolution; circlePoint++)
    59.                 {
    60.                     var index = (maxIterations - 1) * layerResolution + circlePoint;
    61.                     if (circlePoint < layerResolution - 1)
    62.                     {
    63.                         triangles.Add(index);
    64.                         triangles.Add(index + 1);
    65.                         triangles.Add(lastPointIndex);
    66.  
    67.                         triangles.Add(index);
    68.                         triangles.Add(lastPointIndex);
    69.                         triangles.Add(index + 1);
    70.                     }
    71.                     else
    72.                     {
    73.                         triangles.Add(index);
    74.                         triangles.Add(index - layerResolution + 1);
    75.                         triangles.Add(lastPointIndex);
    76.  
    77.                         triangles.Add(index);
    78.                         triangles.Add(lastPointIndex);
    79.                         triangles.Add(index - layerResolution + 1);
    80.                     }
    81.                 }
    82.             }
    83.         }
    84.  
    85.  
    86.         mesh.vertices = positions.ToArray();
    87.         mesh.triangles = triangles.ToArray();
    88.  
    89.         mesh.RecalculateTangents();
    90.  
    91.         mesh.RecalculateNormals();
    92.  
    93.         Vector2[] uv = new Vector2[positions.Count];
    94.         for (int i = 0; i < uv.Length; i++)
    95.         {
    96.             uv[i] = new Vector2(positions[i].x, positions[i].y);
    97.         }
    98.         mesh.uv = uv;
    99.  
    100.         meshCollider.sharedMesh = mesh;
    101.     }
     
  2. tomchambers

    tomchambers

    Joined:
    Mar 21, 2016
    Posts:
    19
    When rendering with a texture, it seems like it's not the UVs that are the problem (not perfect, but do the job for a solid color it seems), but the normals.

     
  3. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Well I'd look at mapping it before you do the procedural distortion if possible. So if the math is twisting this thing, apply uvs before the twist. Then it's just a planar 0..1 thing if that's possible?
     
  4. tomchambers

    tomchambers

    Joined:
    Mar 21, 2016
    Posts:
    19
    It's not quite a twist - each vertex is using a flocking algorithm to decide it's next position as it goes up layer by layer. That might work though if I assume it's a cylinder.

    Although actually the problem seemed to be having a double sided mesh - once I created triangles only for the outside layer of the mesh this problem stopped.