Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Mesh.SetIndexBufferData doesn't render my mesh correctly

Discussion in 'Scripting' started by torano, Jul 9, 2020.

  1. torano

    torano

    Joined:
    Apr 7, 2017
    Posts:
    46
    I am making a voxel base procedural map generator like Minecraft, and to update mesh I use new Mesh API SetVertexBufferParams/SetVertexBufferData/SetIndexBufferParams/SetIndexBufferData but my mesh doesn't render correctly for some reason. It is NOT that my mesh isn't drawn at all, but instead, it is drawn still but sometimes it disapears when a player camera moves or faces towards different direction but when the mesh can be still seen from the player.

    My updating mesh code is like this.
    Code (CSharp):
    1. _mesh.Clear();
    2.  
    3. var vertexCount = _eVertices.Count;
    4. var indexCount = _triangles.Count;
    5.  
    6. _mesh.SetVertexBufferParams(vertexCount, _vertexDescriptor);
    7. // pass vertices and uvs here
    8. _mesh.SetVertexBufferData(_eVertices, 0, 0, vertexCount);
    9.  
    10. _mesh.SetIndexBufferParams(indexCount, _indexFormat);
    11. // pass triangles here
    12. _mesh.SetIndexBufferData(_triangles, 0, 0, indexCount, MeshUpdateFlags.
    13. DontRecalculateBounds
    14. );
    15.  
    16. var subMeshDescriptor = new SubMeshDescriptor(0, indexCount, MeshTopology.Triangles);
    17. subMeshDescriptor.bounds = new Bounds(new Vector3(Extent, Extent, Extent) * ((float)Size - 1f), new Vector3(Extent, Extent, Extent) * 2f * Size);
    18. subMeshDescriptor.vertexCount = vertexCount;
    19. _mesh.subMeshCount = 1;
    20. _mesh.SetSubMesh(0, subMeshDescriptor, MeshUpdateFlags.
    21. DontRecalculateBounds
    22. );
    At first I thought my bounds calculation is incorrect, so I wrote code below to check that.

    Code (CSharp):
    1. void OnDrawGizmos()
    2.         {
    3.             if (_mesh)
    4.             {
    5.                 Gizmos.color = Color.red;
    6.                 var bounds = _mesh.GetSubMesh(0).bounds;
    7.                 // Position is the same as gameObject.transform.position. it is used to see bounds in the world space.
    8.                 Gizmos.DrawWireCube(Position + bounds.center, bounds.size);
    9.             }
    10.         }
    I could see the correct bounds, so I don't know why it doesn't work.
    I tried MeshUpdateFlags.Default for SetIndexBufferData/SetSubMesh instead of manual calculation of bounds and now it gives more accurate bounds instead of my worst case bounds. But sill not work.

    With using Mesh.RecalculateBounds(), I got the correct result(never disapear while the player can see it.), but the bounds is the same as using MeshUpdateFlags.Default without RecalculateBounds(). I think using MeshUpdateFlags.Default recalculates bounds instead of manually calling RecalculateBounds. That is why with that option I got accurate bounds, but I don't know why only MeshUpdateFlags.Default doesn't work but RecalculateBounds() works. If possible, I don't want to use RecalculateBounds() because I think I am calculating the bounds twice now. Another reason is I want to use my manual bounds calculation to reduce bounds calculation(I can calculate it just once). I may be missing something that RecalculateBounds is doing, but I don't know what it is.

    I have used SetVertices/SetTriangles/SetUVs before those new API, so my vertices, uv, and triangles are correct.

    Any advice appreciated.
     
    Last edited: Jul 9, 2020
  2. TheZombieKiller

    TheZombieKiller

    Joined:
    Feb 8, 2013
    Posts:
    265
    Have you tried calculating the bounds for the whole mesh and assigning that to Mesh.bounds after you've applied your mesh data?
     
    IMLCP likes this.
  3. torano

    torano

    Joined:
    Apr 7, 2017
    Posts:
    46
    I think this line or just using _mesh.SetSubMesh(0, subMeshDescriptor, MeshUpdateFlags.Default); does it, doesn't it? I thought that was why the bounds was drawen by Gizmos.DrawWireCube function.
    Code (CSharp):
    1. var subMeshDescriptor = new SubMeshDescriptor(0, indexCount, MeshTopology.Triangles);
    2. subMeshDescriptor.bounds = new Bounds(new Vector3(Extent, Extent, Extent) * ((float)Size - 1f), new Vector3(Extent, Extent, Extent) * 2f * Size);
    3. subMeshDescriptor.vertexCount = vertexCount;
    4. _mesh.subMeshCount = 1;
    5. _mesh.SetSubMesh(0, subMeshDescriptor, MeshUpdateFlags.
    6. DontRecalculateBounds
    7. );