计算顶点法线时的小问题(OpenGL ES)

时间:2011-04-12 23:17:24

标签: opengl 3d light normals

我对顶点法线有点问题。

结果似乎有点奇怪。首先看图像:

3D软件中的原始模型。

http://img233.imageshack.us/img233/4421/screenshot20110412at707.png

每片段照明,直接从OBJ文件导入网格(使用文件中的法线)。

http://img97.imageshack.us/img97/2960/screenshot20110412at708.png

每片段照明,用我自己的例程计算法线。

http://img508.imageshack.us/img508/2960/screenshot20110412at708.png

你注意到了吗? 使用OBJ文件中的法线一切正常。但是当我使用自己的例程来计算基于顶点的法线时,似乎有些不对劲。

当Z变为负值时(使用右手方向),法线似乎很奇怪。在对象的其他部分,一切都很好,但只有一条假想的线穿过网格似乎很奇怪。这个问题在其他网格上仍然存在,总是在同一个地方,Z = 0。

我计算法线的例程是每个人都知道的假设一个带有顶点ABC的三角形:

vec3 normal = normalize(cross(C - A, B - A));

然后将正常结果添加到已计算的正常缓冲区中。

我见过有些人说过计算每个三角形的面积并将其乘以法线甚至检查缓冲区法线和新法线之间的点积,但我已经尝试过这些方法和我发现了一些变化,但仍然存在同样的问题。

你之前见过这个吗?你知道如何解决这个问题吗?

以下是一些代码:


// Looping at each triangle
        vec3 distBA = vec3Subtract(vB, vA);
        vec3 distCA = vec3Subtract(vC, vA);

        vec3 normal = vec3Cross(distBA, distCA);

        // Each normalBuffer represents one vertex.
        normalBuffer[i1] = vec3Add(normal, normalBuffer[i1]);
        normalBuffer[i2] = vec3Add(normal, normalBuffer[i2]);
        normalBuffer[i3] = vec3Add(normal, normalBuffer[i3]);


// After pass through all faces/triangles.


// Looping at each Vertex structure.
        normal = vec3Normalize(normalBuffer[i]);

提前谢谢。

2 个答案:

答案 0 :(得分:1)

根据您对每个碎片光源的计算方式(例如,如果您将点积线夹在0-1范围内),您所看到的可能只是反转法线的问题。根据您选择ABC的方式,顶点处的法线可指向任一方向。要区分三角形的外部和内部,您通常需要更多信息,例如:顶点的缠绕。你考虑到这个吗?

答案 1 :(得分:0)

您是否正常化“然后将正常结果添加到已计算的正常缓冲区中”的结果。我不确定你是否必须,但添加它不会有什么坏处。而且,当你在它时,检查NaN和无穷大。

如果进入的矢量长度大于0,你会检查你的normalize函数吗?

我怀疑你的矢量库中有一个讨厌的错误,特别是因为问题只发生在Z轴上。