Search Unity

Why cube mesh becomes a plane when in high resolution?

Discussion in 'Scripting' started by Deamonpog, Oct 23, 2021.

  1. Deamonpog

    Deamonpog

    Joined:
    Oct 8, 2013
    Posts:
    10
    I use the following code to generate a Cube as a single mesh. My purpose is to generate a sphere from it by normalizing as I have shown in the commented line at line 54 (I just have to do that to all those statements in lines 56 to 62). The problem here is that the mesh changes from a cube to a flat plane as I keep increasing the resolution (parameter given at line 8).

    (This code was inspired by this video :
    But I am using the technique in my own way as given by the following code, so that I can generate a single mesh instead of a combination of 6 meshes, this is required for my work)

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class Sc_Planet : MonoBehaviour
    6. {
    7.     [Range(2, 512)]
    8.     public int resolution = 2;
    9.  
    10.     [Range(2, 256)]
    11.     public int radius = 10;
    12.  
    13.     MeshFilter meshFilter;
    14.  
    15.     void OnValidate()
    16.     {
    17.         Initialize();
    18.     }
    19.  
    20.  
    21.     void Initialize()
    22.     {
    23.         if (meshFilter == null)
    24.         {
    25.             GameObject meshObj = new GameObject("mesh_Planet");
    26.             meshObj.transform.parent = transform;
    27.  
    28.             meshObj.AddComponent<MeshRenderer>().sharedMaterial = new Material(Shader.Find("Standard"));
    29.             meshFilter = meshObj.AddComponent<MeshFilter>();
    30.             meshFilter.sharedMesh = new Mesh();
    31.         }
    32.  
    33.         int xmax = resolution + 1;
    34.         int ymax = resolution + 1;
    35.  
    36.         float dx = 1.0f / resolution;
    37.         float dy = 1.0f / resolution;
    38.  
    39.         Vector3[] vertsTop = new Vector3[xmax * ymax];
    40.         Vector3[] vertsRight = new Vector3[xmax * ymax];
    41.         Vector3[] vertsFront = new Vector3[xmax * ymax];
    42.         Vector3[] vertsBottom = new Vector3[xmax * ymax];
    43.         Vector3[] vertsLeft = new Vector3[xmax * ymax];
    44.         Vector3[] vertsBack = new Vector3[xmax * ymax];
    45.  
    46.         for (int y = 0; y < ymax; y++)
    47.         {
    48.             for (int x = 0; x < xmax; x++)
    49.             {
    50.                 float px = dx * x - 0.5f;
    51.                 float py = dy * y - 0.5f;
    52.                 int t = x + y * xmax;
    53.  
    54.                 //vertsTop[t] = new Vector3(py, 0.5f, px).normalized * radius;
    55.  
    56.                 vertsTop[t] = new Vector3(py, 0.5f, px);
    57.                 vertsRight[t] = new Vector3(px, py, 0.5f);
    58.                 vertsFront[t] = new Vector3(0.5f, px, py);
    59.  
    60.                 vertsBottom[t] = new Vector3(px, -0.5f, py);
    61.                 vertsLeft[t] = new Vector3(py, px, -0.5f);
    62.                 vertsBack[t] = new Vector3(-0.5f, py, px);
    63.             }
    64.         }
    65.  
    66.         List<int> trianglesList = new List<int>();
    67.         for (int y = 0; y < ymax - 1; ++y)
    68.         {
    69.             for (int x = 0; x < xmax; ++x)
    70.             {
    71.                 if (x % xmax != xmax - 1)
    72.                 {
    73.                     int f = x + y * xmax;
    74.  
    75.                     trianglesList.Add(f);
    76.                     trianglesList.Add(f + 1);
    77.                     trianglesList.Add(f + 1 + xmax);
    78.  
    79.                     trianglesList.Add(f);
    80.                     trianglesList.Add(f + 1 + xmax);
    81.                     trianglesList.Add(f + xmax);
    82.                 }
    83.             }
    84.         }
    85.  
    86.         List<Vector3> verts = new List<Vector3>();
    87.         Dictionary<Vector3, int> vdict = new Dictionary<Vector3, int>();
    88.         List<int> triangles = new List<int>();
    89.         int nextIndex = 0;
    90.  
    91.         void addFace(Vector3 [] in_verts, List<int> in_triangles)
    92.         {
    93.             for(int i = 0; i < in_verts.Length; ++i)
    94.             {
    95.                 if (!vdict.ContainsKey(in_verts[i]))
    96.                 {
    97.                     vdict.Add(in_verts[i], nextIndex);
    98.                     verts.Add(in_verts[i]);
    99.                     ++nextIndex;
    100.                 }
    101.             }
    102.  
    103.             for(int i = 0; i < in_triangles.Count; ++i)
    104.             {
    105.                 triangles.Add(vdict[in_verts[in_triangles[i]]]);
    106.             }
    107.         }
    108.  
    109.         addFace(vertsTop, trianglesList);
    110.         addFace(vertsRight, trianglesList);
    111.         addFace(vertsFront, trianglesList);
    112.         addFace(vertsBottom, trianglesList);
    113.         addFace(vertsLeft, trianglesList);
    114.         addFace(vertsBack, trianglesList);
    115.  
    116.  
    117.         var mesh = meshFilter.sharedMesh;
    118.         mesh.Clear();
    119.         mesh.vertices = verts.ToArray();
    120.         mesh.triangles = triangles.ToArray();
    121.         mesh.RecalculateNormals();
    122.     }
    123. }
    124.  
    This code works in Blender (I used python to script it on Blender and it works very well for any resolution).
    The only problem is that when I use this in Unity, the meshes become weird as I have shown in the images I have attached below.

    At Resolution = 96 :
    unity_96.PNG

    At Resolution = 122 :
    unity_122.PNG

    At Resolution = 182 :
    unity_182.PNG
    At Resolution = 344: unity_344.PNG

    Why is this happening?
    How should I correct it?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,752
    Looks like there are two things going on.

    First of all, you are are proposing to make a HELLACIOUS amount of vertices at 344 resolution. Just from some back of envelope math I would estimate 344x344x2x6, which puts you around 1.4 million verts.

    From what I can tell, you are using the 16-bit mesh API that limits you to 64k verts total. Even 96x96 quads times six is going to either exceed that or come pretty close to exceeding it. Look in the docs for using the 32-bit API.

    Second I'm going to guess there is either an outright bug in your transcoding from Python to C#, or else somehow you are reaching the limit of
    float
    precision, and Python was handling it by doing internal calculations in a higher precision format (not sure how Python decides nowadays).
     
    Deamonpog and Bunny83 like this.
  3. Deamonpog

    Deamonpog

    Joined:
    Oct 8, 2013
    Posts:
    10
    Thank you for your answer. I was thinking the same, whether unity have some limit of vertices or triangles.
    I calculated the amount of vertices with a function as given below and got this:

    >>> CalcNumVertices(4)
    98
    >>> CalcNumVertices(256)
    393218
    >>> CalcNumVertices(512)
    1572866
    >>> CalcNumVertices(122)
    89306
    >>> CalcNumVertices(96)
    55298
    >>> CalcNumVertices(99)
    58808
    >>> CalcNumVertices(105)
    66152
    >>> CalcNumVertices(104)
    64898
    >>> CalcNumVertices(102)
    62426

    So it seems I exceed the limit (65535) specified in the documentation given in https://docs.unity3d.com/ScriptReference/Rendering.IndexFormat.html
     
  4. Deamonpog

    Deamonpog

    Joined:
    Oct 8, 2013
    Posts:
    10
    Kurt-Dekker likes this.