我正在使用 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
吗?); - 你需要循环到
width
或depth
包括(使用<= 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
我也看到你交换y
和 z
,这会引起头痛。另外,你反转了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/