gpt4 book ai didi

c# - 在 Unity C# 中修复挤压网格法线?

转载 作者:行者123 更新时间:2023-11-30 17:25:14 59 4
gpt4 key购买 nike

在 Unity C# 中,我正在使用基于平面多边形的 2D 矢量点的程序网格挤压。使用下面的代码效果很好,除了一个细节:似乎每隔一个连接挤压网格正面和背面的三角形都被翻转,如图所示(使用双面着色器,我可以看到所有三角形都这样做存在良好,虽然)。我将如何修复这些桥接法线的翻转?谢谢!

enter image description here

// Extrusion functionality via
// https://forum.unity.com/threads/trying-extrude-a-2d-polygon-to-create-a-mesh.102629/
// with Triangulator based on
// http://wiki.unity3d.com/index.php?title=Triangulator

public static Mesh GetExtrudedMeshFromPoints(Vector2[] points, float depth)
{
const float frontVertex = 0f;

Triangulator triangulator = new Triangulator(points);
int[] tris = triangulator.Triangulate();

Mesh m = new Mesh();
Vector3[] vertices = new Vector3[points.Length*2];

for (int i = 0; i < points.Length; i++)
{
vertices[i].x = points[i].x;
vertices[i].y = points[i].y;
vertices[i].z = frontVertex;
vertices[i+points.Length].x = points[i].x;
vertices[i+points.Length].y = points[i].y;
vertices[i+points.Length].z = depth;
}

int[] triangles = new int[tris.Length*2+points.Length*6];
int count_tris = 0;

// Front vertices
for (int i = 0; i < tris.Length; i += 3)
{
triangles[i] = tris[i];
triangles[i+1] = tris[i+1];
triangles[i+2] = tris[i+2];
}

count_tris += tris.Length;
// Back vertices
for (int i = 0; i < tris.Length; i += 3)
{
triangles[count_tris+i] = tris[i+2] + points.Length;
triangles[count_tris+i+1] = tris[i+1] + points.Length;
triangles[count_tris+i+2] = tris[i] + points.Length;
}

count_tris += tris.Length;
// Triangles around the perimeter of the object
for (int i = 0; i < points.Length; i++)
{
int n = (i+1) % points.Length;
triangles[count_tris] = i;
triangles[count_tris+1] = i + points.Length;
triangles[count_tris+2] = n;
triangles[count_tris+3] = n;
triangles[count_tris+4] = n + points.Length;
triangles[count_tris+5] = i + points.Length;
count_tris += 6;
}

m.vertices = vertices;
m.triangles = triangles;

m.RecalculateNormals();
m.RecalculateBounds();
m.Optimize();

return m;
}

最佳答案

如果一张脸没有显示出来,就像您已经注意到的那样翻转了,这是由于统一的顺时针方向的缠绕顺序。您的 triangluator 链接已在故障排除下说明:“如果您看不到使用此实用程序创建的多边形,请记住检查多边形是否面向相反的方向。如果是,您可以通过以相反的顺序使用顶点索引构建网格来更改它。”

编辑:

进一步说明:在您的代码中,这意味着您必须切换

// Triangles around the perimeter of the object
for (int i = 0; i < points.Length; i++)
{
int n = (i + 1) % points.Length;
triangles[count_tris] = i;
triangles[count_tris + 1] = i + points.Length;
triangles[count_tris + 2] = n;
triangles[count_tris + 3] = n;
triangles[count_tris + 4] = n + points.Length;
triangles[count_tris + 5] = i + points.Length;
count_tris += 6;
}

// Triangles around the perimeter of the object
for (int i = 0; i < points.Length; i++)
{
int n = (i + 1) % points.Length;
triangles[count_tris] = n;
triangles[count_tris + 1] = i + points.Length;
triangles[count_tris + 2] = i;
triangles[count_tris + 3] = n;
triangles[count_tris + 4] = n + points.Length;
triangles[count_tris + 5] = i + points.Length;
count_tris += 6;
}

但要小心,因为顺序取决于你的深度(如果它高于或低于你的 frontVertex)

第二次编辑:

三角形的法线取决于缠绕顺序,这意味着顺序存在差异。

一个例子:

1: Vector2(1f, 1f);
2: Vector2(1f, 0f);
3: Vector2(0f, 0f);

三角形

Triangle 1,2,3

Triangle 1,3,2

有不同的法线。

Winding order of Triangles

您必须确保绘制的每个三角形的缠绕顺序一致。或者你可以告诉你的着色器禁用 culling (使用 Cull Off),正如您在上面所说的。但这伴随着计算时间的成本。在大多数情况下,这并不重要,但这始终取决于您的目的。此外,大多数时候您不希望出现禁用剔除的副作用。

关于c# - 在 Unity C# 中修复挤压网格法线?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58914139/

59 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com