为什么立方体网格在高分辨率下会变成平面?

Why cube mesh becomes a plane when in high resolution?

我使用以下代码将立方体生成为单个网格。我的目的是通过规范化从中生成一个球体,如我在注释行中所示(我只需要对以下行中的所有这些语句执行此操作)。这里的问题是,随着我不断增加分辨率(给定的参数 public int resolution),网格从立方体变为平面。

(此代码的灵感来自于此视频 https://youtu.be/QN39W020LqU。但我正在以我自己的方式使用该技术,如下面的代码所示,这样我就可以生成单个网格而不是 6 个网格的组合网格,这是我工作所必需的)

[code=CSharp]
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Sc_Planet : MonoBehaviour
{
    [Range(2, 512)]
    public int resolution = 2;

    [Range(2, 256)]
    public int radius = 10;

    MeshFilter meshFilter;

    void OnValidate()
    {
        Initialize();
    }


    void Initialize()
    {
        if (meshFilter == null)
        {
            GameObject meshObj = new GameObject("mesh_Planet");
            meshObj.transform.parent = transform;

            meshObj.AddComponent<MeshRenderer>().sharedMaterial = new Material(Shader.Find("Standard"));
            meshFilter = meshObj.AddComponent<MeshFilter>();
            meshFilter.sharedMesh = new Mesh();
        }

        int xmax = resolution + 1;
        int ymax = resolution + 1;

        float dx = 1.0f / resolution;
        float dy = 1.0f / resolution;

        Vector3[] vertsTop = new Vector3[xmax * ymax];
        Vector3[] vertsRight = new Vector3[xmax * ymax];
        Vector3[] vertsFront = new Vector3[xmax * ymax];
        Vector3[] vertsBottom = new Vector3[xmax * ymax];
        Vector3[] vertsLeft = new Vector3[xmax * ymax];
        Vector3[] vertsBack = new Vector3[xmax * ymax];

        for (int y = 0; y < ymax; y++)
        {
            for (int x = 0; x < xmax; x++)
            {
                float px = dx * x - 0.5f;
                float py = dy * y - 0.5f;
                int t = x + y * xmax;

                //vertsTop[t] = new Vector3(py, 0.5f, px).normalized * radius;

                vertsTop[t] = new Vector3(py, 0.5f, px);
                vertsRight[t] = new Vector3(px, py, 0.5f);
                vertsFront[t] = new Vector3(0.5f, px, py);

                vertsBottom[t] = new Vector3(px, -0.5f, py);
                vertsLeft[t] = new Vector3(py, px, -0.5f);
                vertsBack[t] = new Vector3(-0.5f, py, px);
            }
        }

        List<int> trianglesList = new List<int>();
        for (int y = 0; y < ymax - 1; ++y)
        {
            for (int x = 0; x < xmax; ++x)
            {
                if (x % xmax != xmax - 1)
                {
                    int f = x + y * xmax;

                    trianglesList.Add(f);
                    trianglesList.Add(f + 1);
                    trianglesList.Add(f + 1 + xmax);

                    trianglesList.Add(f);
                    trianglesList.Add(f + 1 + xmax);
                    trianglesList.Add(f + xmax);
                }
            }
        }

        List<Vector3> verts = new List<Vector3>();
        Dictionary<Vector3, int> vdict = new Dictionary<Vector3, int>();
        List<int> triangles = new List<int>();
        int nextIndex = 0;

        void addFace(Vector3 [] in_verts, List<int> in_triangles)
        {
            for(int i = 0; i < in_verts.Length; ++i)
            {
                if (!vdict.ContainsKey(in_verts[i]))
                {
                    vdict.Add(in_verts[i], nextIndex);
                    verts.Add(in_verts[i]);
                    ++nextIndex;
                }
            }

            for(int i = 0; i < in_triangles.Count; ++i)
            {
                triangles.Add(vdict[in_verts[in_triangles[i]]]);
            }
        }

        addFace(vertsTop, trianglesList);
        addFace(vertsRight, trianglesList);
        addFace(vertsFront, trianglesList);
        addFace(vertsBottom, trianglesList);
        addFace(vertsLeft, trianglesList);
        addFace(vertsBack, trianglesList);


        var mesh = meshFilter.sharedMesh;
        mesh.Clear();
        mesh.vertices = verts.ToArray();
        mesh.triangles = triangles.ToArray();
        mesh.RecalculateNormals();
    }
}
[/code]

此代码在 Blender 中有效(我使用 python 在 Blender 上编写脚本并且它适用于任何分辨率)。 唯一的问题是,当我在 Unity 中使用它时,网格变得很奇怪,正如我在下面附上的图片中所示。

在分辨率 = 96 时:

在分辨率 = 122 时:

在分辨率 = 182 时:

在分辨率 = 344 时:

为什么会这样? 我该如何纠正?

(我也在 unity 论坛上发过:Why cube mesh becomes a plane when in high resolution?

好的,我找到了答案。这超出了基于 16 位的网格的统一顶点数限制 api。我不得不将其更改为 32 位索引网格以更正它。

详细信息在此文档页面中:https://docs.unity3d.com/ScriptReference/Rendering.IndexFormat.html?_ga=2.9556401.501737799.1635227368-67181881.1629608252

我只需添加代码即可:

mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;

就是这样。