每个顶点超过 1 个法线

Posted

技术标签:

【中文标题】每个顶点超过 1 个法线【英文标题】:More than 1 normal per vertex 【发布时间】:2012-04-03 10:52:58 【问题描述】:

我对从搅拌机导出到 .obj 文件的法线有点困惑 我正在制作一个 win 应用程序,将 obj 文件拆分为 2 个文件,其中 1 个带有顶点,另一个带有索引,因此 opengl 要做的工作更少。 正如我在面孔中看到的那样,我可以找到相同的面孔但法线不同 例如面对 24/24/20 和再次 24/24/19 甚至更多 这是正确的吗? 在搅拌机项目中只有 1 个光源 谢谢

【问题讨论】:

【参考方案1】:

我做了一些测试,下面是我的看法:

OBJ 导出脚本会忽略顶点法线,而是使用面法线。

为了测试,我做了一个简单的形状,由 2 个三角形组成,如下图所示:

并导出到 OBJ。您应该期望 4 个向量法线 (vn),因为您有 4 个向量,或者如果优化了 3 个,因为中间的 2 个向量是相同的。但相反,它只输出 2 个 vn-s:

vn -0.000000 1.000000 0.000000
vn -1.000000 -0.000000 -0.000000

更重要的是,如果您查看面部定义,您会发现更有趣的东西:

f 1//1 4//1 3//1

f 4//2 2//2 3//2

查看单行中 // 后面的数字。他们是一样的。这意味着对于一个面内的所有顶点,使用相同的法线。这意味着,这些不是顶点的法线,而是面的法线。所以这就是为什么为相同的顶点分配不同的法线。当顶点号4 用于定义第一个面接收第一个面的法线,用于定义第二个面时,使用第二个面的法线。

编辑 您可以像这样计算顶点法线:

查找每个顶点的出现并将其所有法线放入集合 A 中 添加法线各自的坐标: vn = (x1 + x2 + ... + xn, y1 + y2 + ... + yn, z1 + z2 + ... + zn) 计算向量长度:h = sqrt(vnx^2 + vny^2 + vnz^2) 归一化向量 vn:vn = (vnx / h, vny / h, vnz / h)

使用我之前的例子(在图像上找到的那个),顶部和底部的向量只出现一次,所以你不需要做任何事情(顶点的法线与顶点的法线相同)脸)。在中间的顶点上:它们出现两次,一次出现在顶部三角形,法线为 (0, 1, 0),底部的法线为 (-1, 0, 0),因此我们这些顶点的法线集是 (0, 1, 0), (-1, 0, 0)。添加这些给出:(0 - 1, 1 + 0, 0 + 0) = (-1, 1, 0)。计算长度:h = sqrt((-1)^2 + 1^2) = sqrt(2)。将向量除以它得到 norm(vn) = vn / h = (-1 / sqrt(2), 1 / sqrt(2), 0)。如果您查看中间法线的 Front Ortho(左上角)的图片,您会看到 -x 和 +y 相等的分量,而向量的长度为 1。您可以看到我们的结果有长度1 通过再次计算它的长度:1/2 + 1/2 + 0 = 1。这就是我们必须归一化以获得长度 1 的原因。

【讨论】:

感谢我们的回复 SinistraD。所以这意味着从 blender 导出和使用法线是没有用的,我们必须自己制作?? 您可以使用面的法线来计算顶点的法线。更新答案:添加过程和示例。 感谢您的 cmets。它们真的非常有用。【参考方案2】:

@SinistraD 感谢您的 cmets。它们真的非常有用。在试图弄清楚如何从每个顶点法线的搅拌器中导出之后,我发现对象工具>阴影>平滑或平坦有一个选项。如果您选择平滑,然后将对象导出为 obj 文件,法线是每个顶点的,我还想在我的项目中尝试它(我现在正在构建着色器)但我很快就会。查看使用此方法导出的多维数据集的示例。

Blender v2.61 (sub 0) OBJ 文件:''

www.blender.org

v 11.209502 -11.209502 -11.209501 v 11.209502 -11.209502 11.209502 v -11.209503 -11.209502 11.209500 v -11.209498 -11.209502 -11.209506 v 11.209508 11.209502 -11.209496 v 11.209495 11.209502 11.209509 v -11.209506 11.209502 11.209498 v -11.209501 11.209502 -11.209502 VT 0.652335 0.642748 VT 0.653298 0.956858 VT 0.339188 0.957821 VT 0.338225 0.643711 VT 0.968372 0.643711 VT 0.967408 0.957821 VT 0.654262 0.642748 VT 0.967408 0.327674 VT 0.968372 0.641784 VT 0.653298 0.328638 VT 0.339188 0.642748 VT 0.338225 0.328638 VT 0.652335 0.327674 VT 0.653298 0.641784 VT 0.337261 0.642748 VT 0.338225 0.956858 VT 0.024115 0.957821 VT 0.023151 0.643711 VT 0.337261 0.327674 VT 0.338225 0.641784 VT 0.024115 0.642748 VT 0.023151 0.328638 vn 0.577349 -0.577349 -0.577349 vn 0.577349 -0.577349 0.577349 vn -0.577349 -0.577349 0.577349 vn -0.577349 -0.577349 -0.577349 vn 0.577349 0.577349 -0.577349 vn -0.577349 0.577349 -0.577349 vn -0.577349 0.577349 0.577349 vn 0.577349 0.577349 0.577349 s 1 f 1/1/1 2/2/2 3/3/3 4/4/4 f 5/5/5 8/6/6 7/2/7 6/7/8 f 1/8/1 5/9/5 6/7/8 2/10/2 f 2/11/2 6/12/8 7/13/7 3/14/3 f 3/15/3 7/16/7 8/17/6 4/18/4 f 5/19/5 1/20/1 4/21/4 8/22/6

【讨论】:

很抱歉通知您,但这在 Blender v2.8 中不起作用:当我选择我的形状/网格时,转到 Object>Shade Smooth 并导出到 OBJ 文件,它仍然有不同的法线关联到该 OBJ 文件的 faces 部分中的相同顶点(以“f”开头的行)。我正在为我的 JAVA 应用程序处理相同的“问题”,但仍在尝试找到一些有用的解决方案,但还没有。

以上是关于每个顶点超过 1 个法线的主要内容,如果未能解决你的问题,请参考以下文章

计算网格的顶点法线[重复]

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

顶点法线的图形问题

OpenGL ES 2.0 每个顶点使用多个法线向量

THREE.BufferGeometry - 顶点法线和面法线

柏林噪声的每顶点法线?