c# - 统一创建一个平面,三角形看起来不对

标签 c# unity3d

我正在使用 C# 统一创建一个平面,我已经让它“工作”了,我得到了一个平面。但是三角形似乎没有正确连接,我不知道为什么。

正如你从那张图片中看到的,它比我能更好地解释它。

我相信问题出在我的索引上,尽管我不确定。

我认为可能还有一个不存在的三角形,所以我认为我的数组也出于某种原因太小了。

Mesh CreatePlane(int width, int depth)
{
    Mesh m = new Mesh();
    int numVert=(width+1)*(depth+1);
    Vector3[] vertecies = new Vector3[numVert];
    Vector2[] uvs = new Vector2[numVert];
    int[] triangles = new int[width*depth*6];

    float uvx = 1.0f/width;
    float uvy = 1.0f/depth;
    int index = 0;


    for (int i = 0;i<width;i++)
    {
        for(int j = 0;j<depth;j++)
        {
            vertecies[index] = new Vector3(i,0,-j);
            uvs[index++] = new Vector2(j*uvx,i*uvy);

        }
    }

    index = 0;
    for(int j=0; j<depth; j++)
    {
        for(int i=0; i<width; i++)
        {

            triangles[index++] = (j * (width+1)) + i;
            triangles[index++] = ((j+1) * (width+1)) + i;
            triangles[index++] = (j * (width+1)) + i + 1;

            triangles[index++] = ((j+1) * (width+1)) + i;
            triangles[index++] = ((j+1) * (width+1)) + i + 1;
            triangles[index++] = (j * (width+1)) + i + 1;

        }
    }

    m.name = "ScriptPlane";
    m.vertices = vertecies;
    m.uv = uvs;
    m.triangles = triangles;
    m.RecalculateNormals();

    return m;
}

最佳答案

你计算 uvx这样:

float uvx = 1.0f/width;

然后你以这种方式在宽度上循环:

for (int i = 0;i<width;i++)
{
    for(int j = 0;j<depth;j++)
    {
        vertecies[index] = new Vector3(i,0,-j);
        uvs[index++] = new Vector2(j*uvx,i*uvy);
    }
}

如果仔细观察,有 2 个错误:

  • j乘以 uvx但它从 0 开始循环至 depth (不应该是 width 吗?);
  • 你需要循环到widthdepth包括(使用 <= width< width + 1 )。

这些只是 UV 坐标,不要将顶点保留在该循环中。它不会解决您的问题,只会解决您稍后会注意到的那 2 个错误。

要解决三角形问题,试试这个:

0 +--+ 2     + 2
  | /       /|
  |/       / |
1 +     1 +--+ 3

0 -> 1 -> 2
2 -> 1 -> 3

为了使背面剔除正常工作,逆时针排列它们很重要。 您可以使用任何其他顺序,有一些非常聪明的解决方案可以切换对角线并保持邻接,这是优化网格缓冲区的旧硬件所必需的。较新的硬件会即时进行这些优化,而不需要您进行计算。

如上所示对三角形缓冲区中的三角形进行排序:

b = (j * width + i) * 6;
triangles[index++] = b + 0;
triangles[index++] = b + 1;
triangles[index++] = b + 2;

triangles[index++] = b + 2;
triangles[index++] = b + 1;
triangles[index++] = b + 3;

此时您所要做的就是正确定位顶点。你发布了这个:

vertecies[index] = new Vector3(i,0,-j);

相反,您应该在单独的循环中执行此操作:

bx = i;
by = -j;
vertecies[index++] = new Vector3(bx + 0, 0, by - 1); // 0
vertecies[index++] = new Vector3(bx + 0, 0, by - 0); // 1
vertecies[index++] = new Vector3(bx + 1, 0, by - 1); // 2
vertecies[index++] = new Vector3(bx + 1, 0, by - 0); // 3

我也看到你交换yz ,这会引起头痛。另外,你反转了j的方向关于世界空间坐标。

我建议你重新考虑一下,正确定位相机并采用标准标记坐标的方式。它将大大简化以后对空间的思考。

如果相机看向-Z那么应该以这种方式计算顶点,而不是:

vertecies[index++] = new Vector3(bx + 0, by + 0, 0); // 0
vertecies[index++] = new Vector3(bx + 0, by + 1, 0); // 1
vertecies[index++] = new Vector3(bx + 1, by + 0, 0); // 2
vertecies[index++] = new Vector3(bx + 1, by + 1, 0); // 3

请注意:这不是简单的代码。小错误(一些 +- 标志或 +1/-1 在某处丢失)是很有可能的,您应该相应地更正它们。这一切都应该让您更好地了解问题,但最终您将不得不运行和调试它,直到它正常工作。

关于c# - 统一创建一个平面,三角形看起来不对,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21885472/

相关文章:

javascript - 理解 RegisterStartupScript : How often will the JavaScript code be called?

c# - 写入只读文件

c# - 按页分类的表格

c# - IEnumerable<T> 和反射

c# - wpf mvvm 嵌套用户控件数据上下文

c# - 统一二维 : Get pixel of color of Raw Image

unity3d - 如何旋转对象以沿向量指向 Unity3D

c# - 来自 PhotoCaptureFrame 的 IMFMediaBuffer

c# - 通过角度差异创建 Vector3 位置

ios - 在原生 iOS 应用程序中使用 Unity 动画