计算 GL_TRIANGLE 的顶点法线

Posted

技术标签:

【中文标题】计算 GL_TRIANGLE 的顶点法线【英文标题】:Calculating Vertex Normals for GL_TRIANGLE 【发布时间】:2014-12-29 14:02:11 【问题描述】:

我正在像这样在 OpenGL 中打印一个三角形:

glBegin(GL_TRIANGLES);
glVertex3f(1,2,3);
glVertex3f(4,6,8);
glVertex3f(5,7,9);
glEnd();

我想计算三角形每个顶点的法线,我想像这样打印三角形:

glBegin(GL_TRIANGLES);
glNormal3f(?,?,?);
glVertex3f(1,2,3);
glNormal3f(?,?,?);
glVertex3f(4,6,8);
glNormal3f(?,?,?);
glVertex3f(5,7,9);
glEnd();

简而言之,我如何计算这个三角形的每个顶点的法线?

【问题讨论】:

【参考方案1】:

您需要计算 2 个边向量的叉积。

Nx = Ay*Bz-Az*By;
Ny = Az*Bx-Ax*Bz;
Nz = Ax*By-Ay*Bx;

其中 A 和 B 是:P1-P0 和 P2-P1 其中 P0, P1, P2 是顶点坐标。

N 应该被归一化并分配给每个顶点。

float len=sqrt(Nx*Nx+Ny*Ny+Nz*Nz);
Nx/=len;
Ny/=len;
Nz/=len;

请注意,如果 P0 P1 P2 以相反的顺序(顺时针)提供,N 法线的符号将被翻转。

【讨论】:

我应该给每个顶点相同的法线吗?谢谢。 需要说明的是,结果必须归一化。 @jason:如果你只有一个三角形,那么每个顶点的法线都是相同的。法线被定义为与下面的表面正交。在三角形的情况下,该表面是平坦的,因此在每个点具有相同的法线。在三角形网格(多个连接的三角形)中,这在许多情况下只是更复杂(弯曲)表面的近似值。在这种情况下,三角形的法线可能不同。 在这种复杂的表面情况下,也可以从共享它的所有三角形中平均给定顶点的法线。 @jason:取决于形状。例如,立方体的每一侧都有一个特定的法线。由相同数量的三角形近似的球体在每个点将具有不同的法线。总结一下:如果你想要三角形之间的平滑过渡,你必须使用更复杂的技术。如果你想要硬边,那么每个三角形使用一个法线就可以了。更详细的解释可以在this post找到。

以上是关于计算 GL_TRIANGLE 的顶点法线的主要内容,如果未能解决你的问题,请参考以下文章

计算顶点法线OpenGL

从顶点数据中获取像素法线

网格颜色混乱可能是由于顶点法线计算错误

在顶点着色器中定位顶点后如何更新法线?

柏林噪声的每顶点法线?

顶点法线的图形问题