glnormalopengl-Square示例

glnormalopengl-Square示例,opengl,Opengl,我很难计算出法线,我想我有一些误解,所以我想举一个简单几何的例子,计算出法线,在这种情况下,应该更清楚如何使用更硬的几何 glBegin(GL_QUADS); glVertex3f(1,1,-1); glVertex3f(1,1,1); glVertex3f(-1,1,1); glVertex3f(-1,1,-1); glEnd(); 在我知道的每个顶点上,我需要输入一个法线值(我想照亮它),所以这表示一个正面的正方形(2

我很难计算出法线,我想我有一些误解,所以我想举一个简单几何的例子,计算出法线,在这种情况下,应该更清楚如何使用更硬的几何

    glBegin(GL_QUADS);
       glVertex3f(1,1,-1);
       glVertex3f(1,1,1);
       glVertex3f(-1,1,1);
       glVertex3f(-1,1,-1);
    glEnd();

在我知道的每个顶点上,我需要输入一个法线值(我想照亮它),所以这表示一个正面的正方形(2x2)。因此,在每个顶点之前,我的法线是否为(0,1.0,0)?

当需要计算四边形的法线时,需要计算四边形的4个顶点的叉积

A = (1, 1, -1)
B = (1, 1, 1)
C = (-1, 1, 1)
D = (-1, 1, -1)
这就是四边形顶点的布局方式。我之所以添加这个,是因为计算以下顶点的顺序很重要

A----B
|    |
|    |
D----C
所以现在当你想计算法线时,你只需要做

normal = (C - A) x (D - B)
其中x表示叉积

叉积 如果你不知道什么是叉积或者如何计算它,那么这里我将告诉你如何计算它

V1 = (C - A)
V2 = (D - B)
然后我们通过以下步骤计算叉积

normal.x = V1.y * V2.z - V1.z * V2.y
normal.y = V2.x * V1.z - V2.z * V1.x
normal.z = V1.x * V2.y - V1.y * V2.x
length = sqrt(x * x + y * y + z * z)

if (length > 0) {
    x /= length
    y /= length
    z /= length
}
if ((x * x + y * y + z * z) != 1) {
    // NORMALIZE THE VECTOR
}
其中,上述3行相当于书写

normal = V1 x V2
现在我们已经计算了叉积,在本例中是一个3D向量

额外的 如果您不知道什么是叉积,并且想了解更多关于它的信息,那么您可以通过这两个链接了解更多关于它的信息

编辑 我做了叉积,它是正常的=(0,8,0),如果我规范化它,我得到(0,1,0)

为了澄清一些事情,我们需要规范化正态分布的原因是,我们正在计算
x,y,z,
01

如果要规范化向量,请执行以下操作

normal.x = V1.y * V2.z - V1.z * V2.y
normal.y = V2.x * V1.z - V2.z * V1.x
normal.z = V1.x * V2.y - V1.y * V2.x
length = sqrt(x * x + y * y + z * z)

if (length > 0) {
    x /= length
    y /= length
    z /= length
}
if ((x * x + y * y + z * z) != 1) {
    // NORMALIZE THE VECTOR
}
此外,如果要检查是否需要规范化向量,可以执行以下操作

normal.x = V1.y * V2.z - V1.z * V2.y
normal.y = V2.x * V1.z - V2.z * V1.x
normal.z = V1.x * V2.y - V1.y * V2.x
length = sqrt(x * x + y * y + z * z)

if (length > 0) {
    x /= length
    y /= length
    z /= length
}
if ((x * x + y * y + z * z) != 1) {
    // NORMALIZE THE VECTOR
}
这是否意味着我只需要在顶点上放置一次,或者我需要在四边形中的每个顶点上提及它

第一条路

glBegin(GL_QUADS);
    glNormal3f(0, 1, 0);
    glVertex3f(1, 1, -1);
    glVertex3f(1, 1, 1);
    glVertex3f(-1, 1, 1);
    glVertex3f(-1, 1, -1);
glEnd();
glBegin(GL_QUADS);
    glNormal3f(0, 1, 0);
    glVertex3f(1, 1, -1);
    glNormal3f(0, 1, 0);
    glVertex3f(1, 1, 1);
    glNormal3f(0, 1, 0);
    glVertex3f(-1, 1, 1);
    glNormal3f(0, 1, 0);
    glVertex3f(-1, 1, -1);
glEnd();
第二种方式

glBegin(GL_QUADS);
    glNormal3f(0, 1, 0);
    glVertex3f(1, 1, -1);
    glVertex3f(1, 1, 1);
    glVertex3f(-1, 1, 1);
    glVertex3f(-1, 1, -1);
glEnd();
glBegin(GL_QUADS);
    glNormal3f(0, 1, 0);
    glVertex3f(1, 1, -1);
    glNormal3f(0, 1, 0);
    glVertex3f(1, 1, 1);
    glNormal3f(0, 1, 0);
    glVertex3f(-1, 1, 1);
    glNormal3f(0, 1, 0);
    glVertex3f(-1, 1, -1);
glEnd();
不管你是用第一种方法还是第二种方法只要你的四边形是平面的,所以如果它是完全平面的,你可以选择第一种或第二种方式

但是如果四边形不是完全平坦的,则需要采用第二种方法,因为四边形的每个顶点将/可能具有不同的法线

许多参考资料都说,您需要计算每个顶点的法线


这是真的,但正如我上面所说的,如果你为一个完全平坦的四边形计算法线,那么每个顶点的法线都是相同的,因此你只需计算一次法线并对每个顶点使用它,就可以节省一些计算/时间/CPU,尽可能长。

当需要计算四边形的法线时,需要计算四边形的4个顶点的叉积

A = (1, 1, -1)
B = (1, 1, 1)
C = (-1, 1, 1)
D = (-1, 1, -1)
这就是四边形顶点的布局方式。我之所以添加这个,是因为计算以下顶点的顺序很重要

A----B
|    |
|    |
D----C
所以现在当你想计算法线时,你只需要做

normal = (C - A) x (D - B)
其中x表示叉积

叉积 如果你不知道什么是叉积或者如何计算它,那么这里我将告诉你如何计算它

V1 = (C - A)
V2 = (D - B)
然后我们通过以下步骤计算叉积

normal.x = V1.y * V2.z - V1.z * V2.y
normal.y = V2.x * V1.z - V2.z * V1.x
normal.z = V1.x * V2.y - V1.y * V2.x
length = sqrt(x * x + y * y + z * z)

if (length > 0) {
    x /= length
    y /= length
    z /= length
}
if ((x * x + y * y + z * z) != 1) {
    // NORMALIZE THE VECTOR
}
其中,上述3行相当于书写

normal = V1 x V2
现在我们已经计算了叉积,在本例中是一个3D向量

额外的 如果您不知道什么是叉积,并且想了解更多关于它的信息,那么您可以通过这两个链接了解更多关于它的信息

编辑 我做了叉积,它是正常的=(0,8,0),如果我规范化它,我得到(0,1,0)

为了澄清一些事情,我们需要规范化正态分布的原因是,我们正在计算
x,y,z,
01

如果要规范化向量,请执行以下操作

normal.x = V1.y * V2.z - V1.z * V2.y
normal.y = V2.x * V1.z - V2.z * V1.x
normal.z = V1.x * V2.y - V1.y * V2.x
length = sqrt(x * x + y * y + z * z)

if (length > 0) {
    x /= length
    y /= length
    z /= length
}
if ((x * x + y * y + z * z) != 1) {
    // NORMALIZE THE VECTOR
}
此外,如果要检查是否需要规范化向量,可以执行以下操作

normal.x = V1.y * V2.z - V1.z * V2.y
normal.y = V2.x * V1.z - V2.z * V1.x
normal.z = V1.x * V2.y - V1.y * V2.x
length = sqrt(x * x + y * y + z * z)

if (length > 0) {
    x /= length
    y /= length
    z /= length
}
if ((x * x + y * y + z * z) != 1) {
    // NORMALIZE THE VECTOR
}
这是否意味着我只需要在顶点上放置一次,或者我需要在四边形中的每个顶点上提及它

第一条路

glBegin(GL_QUADS);
    glNormal3f(0, 1, 0);
    glVertex3f(1, 1, -1);
    glVertex3f(1, 1, 1);
    glVertex3f(-1, 1, 1);
    glVertex3f(-1, 1, -1);
glEnd();
glBegin(GL_QUADS);
    glNormal3f(0, 1, 0);
    glVertex3f(1, 1, -1);
    glNormal3f(0, 1, 0);
    glVertex3f(1, 1, 1);
    glNormal3f(0, 1, 0);
    glVertex3f(-1, 1, 1);
    glNormal3f(0, 1, 0);
    glVertex3f(-1, 1, -1);
glEnd();
第二种方式

glBegin(GL_QUADS);
    glNormal3f(0, 1, 0);
    glVertex3f(1, 1, -1);
    glVertex3f(1, 1, 1);
    glVertex3f(-1, 1, 1);
    glVertex3f(-1, 1, -1);
glEnd();
glBegin(GL_QUADS);
    glNormal3f(0, 1, 0);
    glVertex3f(1, 1, -1);
    glNormal3f(0, 1, 0);
    glVertex3f(1, 1, 1);
    glNormal3f(0, 1, 0);
    glVertex3f(-1, 1, 1);
    glNormal3f(0, 1, 0);
    glVertex3f(-1, 1, -1);
glEnd();
不管你是用第一种方法还是第二种方法只要你的四边形是平面的,所以如果它是完全平面的,你可以选择第一种或第二种方式

但是如果四边形不是完全平坦的,则需要采用第二种方法,因为四边形的每个顶点将/可能具有不同的法线

许多参考资料都说,您需要计算每个顶点的法线


这是真的,但正如我上面所说的,如果你为一个完全平坦的四边形计算法线,那么每个顶点的法线都是相同的,因此你可以通过只计算一次法线并尽可能长地为每个顶点使用它来节省一些计算/时间/CPU。

非常感谢你。。。好的,我做了叉积,它是法线=(0,8,0),如果我规范化它,我得到(0,1,0),这是否意味着我只需要在顶点上放置一次,或者我需要为四边形中的每个顶点提及它。如果这听起来像是愚蠢的问题,我很抱歉,但我以前从未处理过opengl。很多参考资料都说你需要计算每个顶点的法线。好吧,我想我知道需要做什么了。。。非常感谢。again@InsigMath看看我编辑的答案,我回答了你评论的问题。谢谢你更详细的回答,这将有很大帮助!非常感谢你。。。好的,我做了叉积,它是法线=(0,8,0),如果我规范化它,我得到(0,1,0),这是否意味着我只需要在顶点上放置一次,或者我需要为四边形中的每个顶点提及它。