简体   繁体   English

Unity Mesh Renderer 在错误的一侧生成多边形

[英]Unity Mesh Renderer generating polygons on the wrong side

So I need to generate a polygon using the Unity Mesh component that has n number of vertices.所以我需要使用具有 n 个顶点的 Unity Mesh 组件生成一个多边形。 I am using a custom Triangulate() function that is able to find the indices for the mesh.triangles.我正在使用自定义 Triangulate() function,它能够找到 mesh.triangles 的索引。

The problem is that based on the vertices I feed that function, the polygon generates on the wrong side and sometimes is not visible to the camera (unless I flip the camera to the other side).问题是,根据我提供的顶点 function,多边形在错误的一侧生成,有时相机不可见(除非我将相机翻转到另一侧)。

Now I know this has to do with Unity's clockwise winding order, but how can I make sure the polygon is always generated on the correct side, no matter the vertices I feed it?现在我知道这与 Unity 的顺时针缠绕顺序有关,但我如何才能确保多边形始终在正确的一侧生成,无论我提供给它的顶点是什么? Or could there be a way to know on which side the mesh generated so I can adjust the camera accordingly?或者有没有办法知道在哪一侧生成网格,以便我可以相应地调整相机?

The Triangulator function I use我用的三角测量仪 function

This is the normal vector n of a triangle:这是三角形的法向量n

在此处输入图像描述

The visibility of the triangle is based on its normal.三角形的可见性基于其法线。 The math that calculates the light that hits the triangle, is reflected and goes to your eyes (Unity camera) uses the normal of the triangle for that.计算撞击三角形、反射并到达您的眼睛(Unity 相机)的光的数学运算使用三角形的法线。 Basically, if that vector n points towards your eyes it means you can see [part of] the light that hits that surface.基本上,如果该向量n指向您的眼睛,则意味着您可以看到照射到该表面的 [部分] 光。

To know if you can see the triangle, you need to know if the normal points to you.要知道您是否可以看到三角形,您需要知道法线是否指向您。 Without going further with the math, the normal is given by calculating the cross product of the vectors defined by the vertices of the triangle.在不进一步进行数学运算的情况下,通过计算由三角形顶点定义的向量的叉积来给出法线。

For example, a triangle ABC can be defined by the vectors AB and BC (not related with the figure above).例如,一个三角形ABC可以由向量AB和BC定义(与上图无关)。 Or you can invert the "direction" of this triangle and define it AC and CB.或者你可以反转这个三角形的“方向”并定义它 AC 和 CB。 The normal of AB/BC has one direction and the normal of AC/CB has the opposite direction, because of... math - if you google this stuff you can learn why, there are tons of tutorials. AB/BC 的法线有一个方向,而 AC/CB 的法线有相反的方向,因为……数学——如果你用谷歌搜索这些东西你就能知道为什么,有大量的教程。

So I wrote all this to tell something you already know: the order of the vertices defines the visibility.所以我写下所有这些是为了告诉你一些你已经知道的事情:顶点的顺序定义了可见性。 But that's because it defines the direction of the normal.但那是因为它定义了法线的方向。 Now take a look at this code:现在看看这段代码:

        var a = new Vector3(0f, 0f, 0f);
        var b = new Vector3(0.5f, 0.5f, 0f);
        var c = new Vector3(0f, 1f, 0f);

        var ab = b - a;
        var bc = c - b;
        Debug.Log(Vector3.Cross(ab, bc)); // this prints (0.0, 0.0, 0.5)

        var ac = c - a;
        var cb = b - c;
        Debug.Log(Vector3.Cross(ac, cb)); // this prints (0.0, 0.0, -0.5)

Notice that on the second case z is negative, so it's pointing towards you (your camera is probably set at (0, 0, -10) or something similar).请注意,在第二种情况下, z是负数,因此它指向您(您的相机可能设置在 (0, 0, -10) 或类似的位置)。 So if you define the triangle that way you will be able to see it.因此,如果您以这种方式定义三角形,您将能够看到它。

Long story short: to know if you can see a triangle, test the signal of the z component of the cross product of the vertices.长话短说:要知道是否可以看到三角形,请测试顶点叉积的 z 分量的信号。 If the result is not the signal you want, reverse the vertices.如果结果不是您想要的信号,请反转顶点。

I didn't read the code from your triangulator function, but I saw that it's using 2D.我没有从你的三角测量仪 function 中读取代码,但我看到它使用的是 2D。 That means it can probably be simplified further.这意味着它可能可以进一步简化。 It also seems to be calculating the cross product in InsideTriangle() , so you can probably use the calculations that's already going on there to check the signal, with [almost] zero performance loss.它似乎也在计算InsideTriangle()中的叉积,因此您可以使用已经在那里进行的计算来检查信号,[几乎] 性能损失为零。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM