Graphics 一致地确定面法线的方向?
我是计算机图形学的新手,所以如果我的一些语言不准确或者问题遗漏了一些基本的东西,我道歉 在给定顶点列表和如下所示的面列表的情况下,是否可以正确计算面法线:Graphics 一致地确定面法线的方向?,graphics,3d,game-physics,3d-modelling,Graphics,3d,Game Physics,3d Modelling,我是计算机图形学的新手,所以如果我的一些语言不准确或者问题遗漏了一些基本的东西,我道歉 在给定顶点列表和如下所示的面列表的情况下,是否可以正确计算面法线: v1: x_1, y_1, z_1 v2: x_2, y_2, z_2 ... v_n: x_n, y_n, z_n f1: v1,v2,v3 f2: v4,v2,v5 ... f_m: v_j, v_k, v_l 每个x_i,y_i,z_i指定顶点在三维空间中的位置(但不一定是矢量) 每个f_i包含指定它的三个顶点的索引 我知道你可以用一
v1: x_1, y_1, z_1
v2: x_2, y_2, z_2
...
v_n: x_n, y_n, z_n
f1: v1,v2,v3
f2: v4,v2,v5
...
f_m: v_j, v_k, v_l
每个x_i,y_i,z_i
指定顶点在三维空间中的位置(但不一定是矢量)
每个f_i
包含指定它的三个顶点的索引
我知道你可以用一个面两边的叉积得到一条法线,但是法线的方向取决于边的顺序和选择(据我所知)
鉴于这是我仅有的数据,是否有可能正确确定法线的方向?或者是否有可能至少一致地确定它们?(所有法线可能指向错误的方向?在CG中,通过多边形缠绕规则完成。这意味着所有面都已定义,因此当直接在面上查看时,点按CW(或CCW)顺序排列。然后使用叉积将导致一致的法线 但是,许多网格不符合缠绕规则(有些面是CW的,有些面是CCW的,但不完全相同),对于这些网格来说,这是一个问题。我知道有两种方法:
face\u normal
和face\u center-cube\u center
的点积符号将告诉您法线是指向对象的内部还是外部
您甚至可以使用面上的任意点,而不是面中心。无论如何,对于更复杂的凹面形状,这将无法正常工作output_color = face_color * abs(dot(face_normal,light_direction))
一些gfx API已经实现了这一点(查找双面材质或法线,打开它们通常使用abs值…),例如在OpenGL中:
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
一般来说,无法在一组3d面上“一致”指定法线。。。以著名的M比比斯带为例, 您会注意到,如果您在一个循环后开始在其上行走,您将到达相同的点,但位于相反的一侧。换句话说,这条带没有两个面,只有一个面。如果你用一条三角形来构建这样一个形状,当然没有办法以一致的方式指定法线,你必然会得到两个相邻的三角形,法线指向相反的方向 这就是说,如果三角形集合确实是可定向的(即,实际上存在一个一致的法线赋值),则解决方案是从一个三角形开始,然后像洪水填充算法一样传播到邻居。例如,在Python中,它看起来像:
active = [triangles[0]]
oriented = set([triangles[0]])
while active:
next_active = []
for tri in active:
for other in neighbors(tri):
if other not in oriented:
if not agree(tri, other):
flip(other)
oriented.add(other)
next_active.append(other)
active = next_active
谢谢你的回答,如果可能的话,我也会赞同的!
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
active = [triangles[0]]
oriented = set([triangles[0]])
while active:
next_active = []
for tri in active:
for other in neighbors(tri):
if other not in oriented:
if not agree(tri, other):
flip(other)
oriented.add(other)
next_active.append(other)
active = next_active