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

Resolved Display Error with generated Mesh

Discussion in 'Scripting' started by IedSoftworks, May 3, 2022.

  1. IedSoftworks

    IedSoftworks

    Joined:
    May 27, 2021
    Posts:
    12
    Hello there,
    yesterday I worked on a little plane generator with custom subdivisions and support for per-vertex position changes. It works by using the "Quads"-Topology.
    Now I have the following problem: When I do go over 128 subdivisions, it just cuts off, but not only in scene and game view, but also in the mesh inspector. The wierd stuff, the mesh data is still correct, according to the inspector. (i.e. when using 129 subdivisions its at 16900 quads [129 * 129 = 16641 + some float errors], but its actually displaying 16384)
    I have already tried to put the missing vertices in a sub mesh to force them to render on its own. No luck.

    To my setup:
    - Unity 2020.3.26f1 (Personal)
    - Legacy RP
    - No changed settings
    - Plugins: DOTween, Input System, Gridbox Prototype Materials
    - Test Object has: a Mesh Filter, a Mesh Renderer with Prototype Blue1 applied, my Test-Script

    If anyone has some experience with that, I would be happy to hear how you solved this issue.

    Thanks you,
    iedSoftworks

    https://imgur.com/a/5U51l2V

    My Script (removed everything that isn't neccary for the generation):

    Code (CSharp):
    1.         public enum MeshOptimization
    2.         {
    3.             None,
    4.            
    5.             VertexBuffer,
    6.             IndexBuffer,
    7.            
    8.             Full
    9.         }
    10.  
    11.         private struct MeshContents
    12.         {
    13.             public Vector3[] Vertices;
    14.             public Vector2[] UVs;
    15.             public int[] Indecies;
    16.             public MeshTopology Topology;
    17.         }
    18.  
    19.         private Vector3 _center; // (0,0,0)
    20.         private Vector3 _size; // (25,0,25)
    21.         private Vector3Int _subdivitions; // (129,129,129)
    22.         private MeshOptimization _optimization; // Full
    23.         private VertexTranslation _vertexTranslation; // not used, but can be used to translate the vertices
    24.         private MeshTopology? _forcedTopology; // null
    25.        
    26.         public Mesh Build(bool forceNewMesh = false) // false
    27.         {
    28.             if (forceNewMesh || _reusableMesh == null)
    29.             {
    30.                 _reusableMesh = new Mesh();
    31.             }
    32.             MeshContents contents = _genFunction(this); // _genFunction is set to PlaneGeneration
    33.             Debug.Log(contents.Vertices.Length);
    34.            
    35.             _reusableMesh.SetVertices(contents.Vertices);
    36.            
    37.             if (contents.UVs != null) _reusableMesh.SetUVs(0, contents.UVs);
    38.             _reusableMesh.SetIndices(contents.Indecies, _forcedTopology.GetValueOrDefault(contents.Topology), 0);
    39.  
    40.             _reusableMesh.RecalculateNormals();
    41.             if (_optimization <= 0) return _reusableMesh;
    42.            
    43.            
    44.             switch (_optimization)
    45.             {
    46.                 case MeshOptimization.VertexBuffer:
    47.                     _reusableMesh.OptimizeReorderVertexBuffer();
    48.                     break;
    49.                 case MeshOptimization.IndexBuffer:
    50.                     _reusableMesh.OptimizeIndexBuffers();
    51.                     break;
    52.                 case MeshOptimization.Full:
    53.                     _reusableMesh.Optimize();
    54.                     break;
    55.                 default:
    56.                     throw new ArgumentOutOfRangeException();
    57.             }
    58.  
    59.             return _reusableMesh;
    60.         }
    61.  
    62.         private static MeshContents PlaneGeneration(MeshGenerator mesh)
    63.         {
    64.             Vector3 steps = GetSteps(mesh);
    65.  
    66.             int i = 0;
    67.             List<Vector3> vertices = new List<Vector3>();
    68.             List<Vector2> UVs = new List<Vector2>();
    69.             List<int> indecies = new List<int>();
    70.             for (float x = 0; x < mesh._size.x; x += steps.x)
    71.             {
    72.                 for (float z = 0; z < mesh._size.z; z += steps.z)
    73.                 {
    74.                    
    75.                     Vector3 br = GetCorrectPosition(mesh, new Vector3(x, 0, z));
    76.                     Vector3 bl = GetCorrectPosition(mesh, new Vector3(x + steps.x, 0, z));
    77.                     Vector3 tl = GetCorrectPosition(mesh, new Vector3(x + steps.x, 0, z + steps.z));
    78.                     Vector3 tr = GetCorrectPosition(mesh, new Vector3(x, 0, z + steps.z));
    79.                    
    80.                     vertices.AddRange(new []{br, tr, tl, bl});
    81.                     indecies.AddRange(new []{i, i+1, i+2, i+3});
    82.                     UVs.AddRange(new []
    83.                     {
    84.                         new Vector2(x, z),
    85.                         new Vector2(x, z + steps.z),
    86.                         new Vector2(x + steps.x, z + steps.z),
    87.                         new Vector2(x + steps.x, z),
    88.                     });
    89.  
    90.                     i += 4;
    91.                 }
    92.                
    93.             }
    94.            
    95.             return new MeshContents()
    96.             {
    97.                 Topology = MeshTopology.Quads,
    98.                 Indecies = indecies.ToArray(),
    99.                 Vertices = vertices.ToArray(),
    100.                 UVs = UVs.ToArray()
    101.             };
    102.         }
    103.  
    104.         private static Vector3 GetSteps(MeshGenerator mesh)
    105.         {
    106.             return new Vector3(
    107.                 mesh._size.x / mesh._subdivitions.x,
    108.                 mesh._size.y / mesh._subdivitions.y,
    109.                 mesh._size.z / mesh._subdivitions.z);
    110.         }
    111.  
    112.         private static Vector3 GetCorrectPosition(MeshGenerator mesh, Vector3 pos)
    113.         {
    114.             pos -= mesh._size / 2;
    115.             pos += mesh._center;
    116.             if (mesh._vertexTranslation != null)
    117.                 pos = mesh._vertexTranslation(pos);
    118.            
    119.             return pos;
    120.         }
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,951
    Bunny83 likes this.
  3. IedSoftworks

    IedSoftworks

    Joined:
    May 27, 2021
    Posts:
    12
    Oh. interesting. Yes I checked the vert count, but I didn't knew there was something like an index format, since I was using "int"s and those are usually already 32-bit. (according to the c# documentation)

    But now I change it, when the vertex counts exceeds 65535 and it works. :D
    Thank you so much.
     
    Kurt-Dekker likes this.