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. Dismiss Notice

Mapping UVs to the 3D hex mesh

Discussion in 'Scripting' started by Xoroxoxoxoxoso, Jan 18, 2015.

  1. Xoroxoxoxoxoso

    Xoroxoxoxoxoso

    Joined:
    Jul 26, 2012
    Posts:
    80
    Hi,
    I have generated 3D mesh in Unity and now I am trying to add UVs to this mesh. I managed to do that when it was in 2D. But I don't know how to do it in 3D. Do you guys have any idea? Thank you for your help.

    EDIT: I have added code for my hex mesh

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class HexInfo : MonoBehaviour {
    5.  
    6.     public Texture texture;
    7.  
    8.     // Basix hexagon mesh making
    9.     private Vector3[] vertices;
    10.     private Vector2[] uv;
    11.     private int[] triangles;
    12.  
    13.     void Start ()
    14.     {
    15.         MeshSetup();
    16.     }
    17.  
    18.     void MeshSetup()
    19.     {
    20.         #region VERTICES
    21.  
    22.         float height = 0.125f;
    23.         float floorLevel = 0.0f + height;
    24.         vertices = new Vector3[]
    25.         {
    26.             // Top
    27.             new Vector3(-1.0f, floorLevel, -0.5f),
    28.             new Vector3(-1.0f, floorLevel, 0.5f),
    29.             new Vector3(0.0f, floorLevel, 1.0f),
    30.             new Vector3(1.0f, floorLevel, 0.5f),
    31.             new Vector3(1.0f, floorLevel, -0.5f),
    32.             new Vector3(0.0f, floorLevel, -1.0f),
    33.  
    34.             // Bottom
    35.             new Vector3(-1.0f, floorLevel - height, -0.5f),
    36.             new Vector3(-1.0f, floorLevel - height, 0.5f),
    37.             new Vector3(0.0f, floorLevel - height, 1.0f),
    38.             new Vector3(1.0f, floorLevel - height, 0.5f),
    39.             new Vector3(1.0f, floorLevel - height, -0.5f),
    40.             new Vector3(0.0f, floorLevel - height, -1.0f)
    41.         };
    42.  
    43.         #endregion
    44.  
    45.  
    46.         #region TRIANGLES
    47.  
    48.         triangles = new int[]
    49.         {
    50.             // Top
    51.             1, 5, 0,
    52.             1, 4, 5,
    53.             1, 2, 4,
    54.             2, 3, 4,
    55.            
    56.             // Bottom
    57.             7, 6, 11,
    58.             7, 11, 10,
    59.             7, 10, 8,
    60.             8, 10, 9,
    61.  
    62.             // Sides
    63.             0, 11, 6,
    64.             0, 5, 11,
    65.  
    66.             5, 10, 11,
    67.             5, 4, 10,
    68.  
    69.             4, 9, 10,
    70.             4, 3, 9,
    71.  
    72.             3, 8, 9,
    73.             3, 2, 8,
    74.  
    75.             2, 7, 8,
    76.             2, 1, 7,
    77.  
    78.             1, 6, 7,
    79.             1, 0, 6
    80.  
    81.         };
    82.  
    83.         #endregion
    84.  
    85.  
    86.         #region UV
    87.  
    88.         uv = new Vector2[]
    89.         {
    90.             /*
    91.             new Vector2(0.0f, 0.25f),
    92.             new Vector2(0.0f, 0.75f),
    93.             new Vector2(0.5f, 1.0f),
    94.             new Vector2(1.0f, 0.75f),
    95.             new Vector2(1.0f, 0.25f),
    96.             new Vector2(0.5f, 0.0f),
    97.             */
    98.         };
    99.  
    100.         #endregion
    101.  
    102.  
    103.         #region FINALIZE
    104.  
    105.         // Add a mesh filter to the game object the script is attached to. Cache it for later
    106.         MeshFilter meshFilter = this.gameObject.AddComponent<MeshFilter>();
    107.         // Add a mesh renderer to the game object to the script is attached to
    108.         this.gameObject.AddComponent<MeshRenderer>();
    109.  
    110.         // Create a mesh object to pass our data into
    111.         Mesh mesh = new Mesh();
    112.  
    113.         // Add our vertices to the mesh
    114.         mesh.vertices = vertices;
    115.         // Add our triangles to the mesh
    116.         mesh.triangles = triangles;
    117.         // Add our uv coordinates to the mesh
    118.         //mesh.uv = uv;
    119.  
    120.  
    121.         // Recalculate normals for lighting
    122.         mesh.RecalculateNormals();
    123.  
    124.         // Set the gameobject's meshFilter's mesh to tbe the one we just made
    125.         meshFilter.mesh = mesh;
    126.  
    127.         // Test our uv
    128.         this.renderer.material.mainTexture = texture;
    129.  
    130.         #endregion
    131.     }
    132. }
    133.  
     
  2. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    It depends entirely on how you want it to be mapped.
    Note: Since you only have one vertex at each point, you can only have one UV coord (vertex count must == uv count)
    This means no texture seams (Which is likely going to be prohibitive to desired results). Youll probably have to add more verts, and change the triangles, etc.
     
  3. Glurth

    Glurth

    Joined:
    Dec 29, 2014
    Posts:
    109
    >>(vertex count must == uv count)...Youll probably have to add more verts, and change the triangles, etc.

    So if I have a particular vertex in a mesh, that is used in say.. four triangles: In order to use one UV coordinate for triangles 1&2, and another UV coordinate for triangles 3&4, I must create another vertex (even though it will have identical coordinates)?
     
    Last edited: Jan 18, 2015
  4. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    Yep. And as a consequence, you must change the vert index used in each of those triangles
     
  5. Xoroxoxoxoxoso

    Xoroxoxoxoxoso

    Joined:
    Jul 26, 2012
    Posts:
    80
    Hmm, I have always thought that vertex coordinates should be between 0 and 1.
    I am not sure if I understand it right, where am I suppose to add those vertices? Can you provide me a example please?
     
  6. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    Heres a cylinder with a gradient texture, mapped to wrap all the way around

    The cylinder has 20 vertex positions around it's circumference, but in order to get the sharp boundary at the edge of the texture, you need 2 different uvs ( [0,0] and [1,0] ) at the vertex position, so there are actually 21 verts around each ring, with the first and last being in the exact same position
     
    Glurth likes this.
  7. Glurth

    Glurth

    Joined:
    Dec 29, 2014
    Posts:
    109
    And if we wanted the END of those cylinders to map the same gradient across their surface, we would need ANOTHER 20 vertices with their own uv mapping [to (sin angle,cos angle) and (0.5,0.5) for the center]

    This seems kind of odd to me. is there a reason the UV (and Normals array too, I see) are not also indexed like vertices? This would allow us to mix and match UNIQUE vertex, normal, and uv information. Is it because SPEED is more important that memory usage? In which case, why use indexes for vertices at all? (not complaining, just curious)
     
  8. Glurth

    Glurth

    Joined:
    Dec 29, 2014
    Posts:
    109
    The vertex coordinate is a point in 3D space (model space, specifically).
    A UV coordinate, is a 2D point on your texture. THESE x,y UV values are between 0 and 1 (top/bottom of texture, leftside /rightside of texture).
    [details: The graphics engine interpolates what texture pixels go BETWEEN your triangles vertices(in 3D-space), by looking at their UV coordinates. I would guess it does this by using some kind of projection matrix to convert the 3D Vertex coordinates into 2d coordinates, and then interpolating between each of the triangle's vertex's UV coordinates (a 2D texture-space coordinate), to find the pixel color.]

    Edit: It is standard practice for shapes to be a 1 unit in size, in model space (x,y,z)... perhaps this is why you thought vertices should be between 0 and 1? Though this usually yields a min/max for each coordinate of -0.5 to 0.5