Unity单个Mesh顶点数是否有限制?岛屿网格生成异常求助
Unity单个Mesh顶点数限制导致多层岛屿仅渲染前两层的问题解决
我在Unity中通过遍历网格Cell,用顶点构建立方体并合并到单个Mesh生成岛屿。代码如下:
void DrawTerrainMesh(Cell[,,] grid){ Mesh mesh = new(); List<Vector3> vertices = new List<Vector3>(); List<int> triangles = new List<int>(); for (int z = 0; z < z_size; z++) { for (int y = 0; y < size; y++) { for (int x = 0; x < size; x++) { Cell cell = grid[x, y, z]; if (cell == null) continue; if (cell.cellType == Cell.CellType.Earth) { // Calculate the positions of the 8 vertices Vector3[] cubeVertices = new Vector3[8]; for (int i = 0; i < 2; i++) { float xv = i == 0 ? 0.5f : -0.5f; for (int j = 0; j < 2; j++) { float yv = j == 0 ? 0.5f : -0.5f; for (int k = 0; k < 2; k++) { float zv = k == 0 ? 0.5f : -0.5f; Vector3 vertex = new Vector3(xv + x - size/2, zv + z,yv + y - size/2); cubeVertices[i * 4 + j * 2 + k] = vertex; } } } AddTriangles(vertices, triangles, cubeVertices[0], cubeVertices[2], cubeVertices[4], cubeVertices[6]); // Top AddTriangles(vertices, triangles, cubeVertices[0], cubeVertices[1], cubeVertices[2], cubeVertices[3]); // left AddTriangles(vertices, triangles, cubeVertices[2], cubeVertices[3], cubeVertices[6], cubeVertices[7]); // back AddTriangles(vertices, triangles, cubeVertices[3], cubeVertices[1], cubeVertices[7], cubeVertices[5]); // Bottom AddTriangles(vertices, triangles, cubeVertices[4], cubeVertices[6], cubeVertices[5], cubeVertices[7]); // right AddTriangles(vertices, triangles, cubeVertices[0], cubeVertices[4], cubeVertices[1], cubeVertices[5]); // front */ } } } } mesh.vertices = vertices.ToArray(); mesh.triangles = triangles.ToArray(); mesh.RecalculateNormals(); print(mesh.vertices.Length); MeshFilter meshFilter = gameObject.AddComponent<MeshFilter>(); meshFilter.mesh = mesh; MeshRenderer meshRenderer = gameObject.AddComponent<MeshRenderer>(); }
当前岛屿本该有多层结构,但仅渲染出前两层;但只绘制立方体顶面时,所有层都能正常显示。我猜测是Unity对单个Mesh的顶点数有限制,想确认这个猜测是否正确,以及该怎么解决?
你的猜测完全正确,Unity的Mesh确实存在顶点数限制:默认情况下大多数平台使用16位索引,单个Mesh的顶点数上限是65535。当顶点数超过这个值时,超出部分会被截断,导致渲染异常,这就是你只看到前两层的原因。
只渲染顶面时,每个立方体仅添加4个顶点,总顶点数远低于上限,所以能正常显示;而渲染完整立方体时,你的代码每个立方体重复添加24个顶点(6个面,每个面4个顶点),很快就会突破65535的限制。
解决方法
1. 启用32位索引(快速解决)
Unity支持切换到32位索引,将顶点数上限提升到4294967295,完全满足大多数场景需求。只需在设置Mesh的triangles之前添加一行代码:
mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
修改后的关键代码片段:
mesh.vertices = vertices.ToArray(); mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; // 新增这行 mesh.triangles = triangles.ToArray(); mesh.RecalculateNormals();
2. 优化顶点共享(长期优化)
你的代码当前每个立方体都重复添加相同位置的顶点,造成大量冗余。可以通过共享顶点来大幅减少顶点总数,比如用字典记录已添加的顶点位置和对应的索引,复用已有顶点:
// 新增字典记录顶点索引 Dictionary<Vector3, int> vertexIndexMap = new Dictionary<Vector3, int>(); // 获取顶点索引,已存在则复用,不存在则添加 int GetVertexIndex(Vector3 vertex) { if (vertexIndexMap.TryGetValue(vertex, out int index)) { return index; } vertices.Add(vertex); index = vertices.Count - 1; vertexIndexMap.Add(vertex, index); return index; } // 修改AddTriangles方法,使用索引而非直接添加顶点 void AddTriangles(List<int> triangles, Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4) { int idx1 = GetVertexIndex(v1); int idx2 = GetVertexIndex(v2); int idx3 = GetVertexIndex(v3); int idx4 = GetVertexIndex(v4); // 添加两个三角形 triangles.Add(idx1); triangles.Add(idx2); triangles.Add(idx3); triangles.Add(idx1); triangles.Add(idx3); triangles.Add(idx4); }
这样相邻立方体共享的顶点只会被添加一次,顶点总数会大幅降低,同时也能避免顶点数超限的问题。
内容的提问来源于stack exchange,提问作者user19013678
相关产品推荐
相关产品推荐

