3

我对顶点法线有一点问题。

结果似乎有点奇怪。首先看一下图片:

3D 软件中的原始模型。

Per-Fragment 光照,直接从 OBJ 文件导入网格(使用文件中的法线)。

Per-Fragment 光照,用我自己的例程计算法线。

你注意到了吗?使用 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]);
4

2 回答 2

1

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

于 2011-04-14T14:56:27.483 回答
0

您是否正在对“然后将正常结果添加到已计算的正常缓冲区。”的结果进行规范化。我不确定你必须这样做,但添加它不会有什么坏处。并且,当您使用它时,检查 NaN 和无穷大。

如果输入的向量的长度大于 0,你会检查你的归一化函数吗?

我怀疑您的向量库中某处有一个讨厌的错误,特别是因为该问题仅发生在 Z 轴上。

于 2011-04-13T17:20:57.940 回答