计算面部法线和弯曲 [英] Computing face normals and winding
问题描述
如何计算多面体的每个面的曲面法线?
我需要曲面法线才能计算顶点法线来执行 Gouraud阴影。我能找到的关于如何做到这一点的唯一线索是纽维尔的方法,但我如何确保法线是外向法线而不是内向?感谢您的帮助。
计算脸部正常
必须计算跨越包含给定面的平面的两个向量的叉积。它为您提供该面部的(非单位)法线向量。如果 x0
, x1 ,那么您必须将它归一化并完成。 code>,
x2
是三角形面的顶点,那么法线可以计算为:
vector3 get_normal(vector3 x0,vector3 x1,vector3 x2)
{
vector3 v0 = x0 - x2;
vector3 v1 = x1 - x2;
vector3 n = cross(v0,v1);
return normalize(n);
}
请注意,叉积符合右侧规则:
右边的规则指出,向量的交叉
乘积的方向是通过将 u 和 v 从尾到尾
压扁右手,将其向 u 方向延伸,然后
然后沿角度 v 使
与<强>û即可。拇指然后指向 cross(u,v)的方向。
三角形
为了确保所有法线都指向多面体的内部/外部,三角形必须是一致的,这意味着所有的顶点必须遵循逆时针(CCW)或顺时针(CW)顺序。您也可以通过计算下面矩阵的行列式来检查三角形的方向,其中 x3 code>是第四点,您在测试期间的观点。
| x0.x x0.y x0.z 1 |
| x1.x x1.y x1.z 1 |
| x2.x x2.y x2.z 1 |
| x3.x x3.y x3.z 1 |
- 行列式> 0:
{x0,x1,x2}定义的平面的
+
/ code> - 行列式< 0:>
x3
位于由CCW点-
> {x0,x1,x2} - 行列式= 0
x3
与{x0,x1,x2}共同
(通过左右移动所有的顶点)不会改变方向。因此 {x0,x1,x2}
的方向与 {x2,x0,x1}
和。
然而,如果交换两个连续元素的顺序,方向。这意味着 {x0,x1,x2}
的方向与 {x1,x0,x2}
相反。
使用此信息可以轻松定位三角形:使用谓词矩阵测试每个三角形。如果测试失败,只需交换任意两个连续顶点元素的顺序并解决问题。
Given a convex polyhedron with defined vertices (x, y, z) that specifies the faces of the polyhedron.
How can I go about calculating the surface normal of each face of the polyhedron?
I need the surface normal in order to compute the vertex normal to perform Gouraud shading. The only clue I could find about how to do this is Newell's method, but how do I make sure the normals are outward normals and not inward? Thanks for any help.
Compute the face normal
You have to compute the cross product of two vectors spanning the plane that contains the given face. It gives you the (non-unit) normal vector of that face. You have to normalize it and you are done.
If x0
, x1
, x2
are the vertices of a triangular face, then the normal can be computed as
vector3 get_normal(vector3 x0, vector3 x1, vector3 x2)
{
vector3 v0 = x0 - x2;
vector3 v1 = x1 - x2;
vector3 n = cross(v0, v1);
return normalize(n);
}
Note that the cross product follows the right-hand rule:
The right-hand rule states that the orientation of the vectors' cross product is determined by placing u and v tail-to-tail, flattening the right hand, extending it in the direction of u, and then curling the fingers in the direction that the angle v makes with u. The thumb then points in the direction of cross(u, v).
Orient your triangles
To make sure that all your normals are pointing inside/outside of the polyhedron, the triangles must be uniformly oriented, which means that all the vertices must follow a counter-clockwise (CCW) or clockwise (CW) order. This is also called winding in computer graphics.
You can check the orientation of your triangles by computing the determinant of the matrix below where x3
is a fourth point, your view point during the test.
| x0.x x0.y x0.z 1 |
| x1.x x1.y x1.z 1 |
| x2.x x2.y x2.z 1 |
| x3.x x3.y x3.z 1 |
- determinant > 0:
x3
is on the+
side of the plane defined by CCW points{ x0, x1, x2 }
- determinant < 0:
x3
is on the-
side of the plane defined by CCW points{ x0, x1, x2 }
- determinant = 0:
x3
is coplanar with{ x0, x1, x2 }
Rotating the order of the vertices (by shifting all of them left or right) doesn't change the orientation. So { x0, x1, x2 }
has the same orientation as { x2, x0, x1 }
and { x1, x2, x0 }
.
However if you swap the order of two consecutive elements, you also swap to the opposite orientation. It means that { x0, x1, x2 }
has the opposite orientation as { x1, x0, x2 }
.
Using this information you can easily orient your triangles: test each triangle using the predicate matrix. If the test fails, simply swap the order of any two consecutive vertex elements and problem solved.
这篇关于计算面部法线和弯曲的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!