2

我想知道为什么当我使用 Assimp 库导入 Wavefront 对象文件(.obj)时,它会使某些顶点加倍,我在 Assimp SourceForge 讨论中找到了以下答案(http://sourceforge.net/p/assimp/discussion/ 817654/thread/026e9640/?limit=25#ba6c):

想象一下:您将一系列顶点上传到显卡。然后,您通过索引缓冲区告诉 GPU,您希望第一个三角形由顶点 3、6 和 7 组成。第二个三角形是 1、2 和 6。会发生什么?GPU 会为您绘制一个立方体,但立方体的每个角都将共享相同的 UV 数据、法线向量、顶点颜色或您的网格所需的任何其他内容。

现在我们如何获得一个立体角,但在接触该角的所有侧面都获得不同的 UV 映射?我们不能告诉 GPU “使用顶点 3,但不要使用该顶点的 UV 坐标,而是请使用 UV 坐标”。GPU 无法做到这一点。这就是为什么有必要在那个角落复制顶点。现在您有两个顶点用于相同的位置,但具有不同的 UV 坐标。

这就是 Assimp 正在为您做的事情。如果您确实指定了 JoinIdenticalVertices,您将获得一个具有 24 个顶点的立方体。为什么?一个立方体有 8 个角,但每个角有 3 个立方体面相接触,每个立方体面都为该角设置了不同的 UV 坐标,因此您最终会得到每个角的 3 个版本。如果您不指定 JoinIdenticalVertices,您将获得一个没有任何重用的普通顶点数组。这意味着您需要 2 个三角形,每个立方体的每个边都有 3 个顶点,最终有 36 个顶点。

另一种方法是使用 3D uv 坐标和立方体贴图来纹理该立方体。这是一个仅适用于多维数据集的特殊情况,但在那里它会起作用。然后 GPU 在内部映射到 6 个纹理。上面的描述是一般情况,它适用于您可能遇到的每个网格。

这确实有道理。
假设我不知道 MeshLab 如何处理 .obj 导入操作,如果我找到的答案是正确的,那么当我导入这样的对象时,顶点计数器不会增加?仅仅是他们如何进行计数的问题,还是有办法导入 .obj 文件而不必在顶点有法线/切线/UV时拆分它们?

4

1 回答 1

2

这不是特定于实现的(例如,它们有几个向量 - 每个变量一个),但逻辑是相同的。

Meshlab 为每个 3D 坐标生成一个顶点,除了公共位置之外,还有几个可能的变量“值”,例如法线和纹理。这些顶点存储在顶点向量中。

这些多个值存储在单独的顶点数据向量中(我将其称为 VDV)。三角形面将指向 VDV 中的 3 个条目,但一个顶点可以指向任意数量的条目。

在渲染时,VDV 将用于索引目的,但在计算内容和计算顶点数时使用实际顶点。他们对正常的东西有单独的“组合”值,考虑到他们所有的相邻面孔。

于 2015-07-09T15:09:56.570 回答