【问题标题】:Little problem while calculating vertex normals (OpenGL ES)计算顶点法线时的小问题(OpenGL ES)
【发布时间】:2011-08-04 07:18:15
【问题描述】:

我的顶点法线有点问题。

结果似乎有点奇怪。先来看看图片:

3D 软件中的原始模型。

每片段光照,直接从 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]);

【问题讨论】:

  • 鉴于错误似乎是每个像素而不是每个多边形,因此错误可能在着色器中,您能否也发布代码?
  • 另外,我不确定我为什么要添加法线到普通缓冲区而不是仅仅设置它们?
  • 两种情况下的着色器是相同的(来自 OBJ 的法线,由我计算)。使用来自 OBJ 的法线,一切正常,所以我认为问题不存在。缓冲区是对同一顶点但来自不同三角形的法线求和,就像三角形相邻。我真的不明白为什么会这样。
  • 但问题可能出在代码的两个部分,例如着色器可能无法处理输入数据的某些问题(例如,非标准化法线,尽管我可以看到您确实在对它们进行标准化)。我要做的另一个测试是:只使用第一个计算的法线而不是添加 + 规范化,这样可以排除这部分代码的任何问题。
  • 另一个要运行的测试:渲染一个三角形穿越z=0线。这将清楚地显示问题的一部分是否在阴影中。另外:禁用镜面反射。一般来说,尽量简化测试用例,排除各种“干扰”。

标签: opengl-es light normals


【解决方案1】:

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

【讨论】:

  • 我已经尝试了 A、B、C 的所有计算组合...其他结果绝对错误...我仍在寻找解决方案..
  • 我的意思有点不同。我并不是说您以错误的顺序选择 A、B、C。我是说订单可能取决于其他一些信息,这些信息可能对一半茶壶正确,而对另一半错误。因此,在这种情况下,我不希望任何特定的组合是正确的。无论如何,如果尝试所有这些都没有给您任何额外的见解,那么它可能没有朝着正确的方向发展。
【解决方案2】:

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

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

我怀疑您的向量库中某处存在严重错误,尤其是因为该问题仅发生在 Z 轴上。

【讨论】:

  • 是的,伙计……我已经按照你说的做了……这快把我逼疯了……看,我编辑了问题,在那里添加了一些代码。
猜你喜欢
  • 1970-01-01
  • 2013-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-15
  • 2012-01-13
  • 1970-01-01
  • 2013-09-14
相关资源
最近更新 更多