61

我有一些顶点数据。位置、法线、纹理坐标。我可能从 .obj 文件或其他格式加载它。也许我在画一个立方体。但是每条顶点数据都有自己的索引。我可以使用 OpenGL/Direct3D 渲染这个网格数据吗?

4

2 回答 2

76

在最一般的意义上,没有。OpenGL 和 Direct3D 只允许每个顶点有一个索引;索引从每个顶点数据流中获取。因此,每个唯一的组件组合都必须有自己的单独索引。

因此,如果您有一个立方体,其中每个面都有自己的法线,您将需要大量复制位置和法线数据。您将需要 24 个位置和 24 个法线,即使立方体只有 8个唯一位置和 6 个唯一法线。

您最好的选择是简单地接受您的数据会更大。许多模型格式将使用多个索引;您需要先修复此顶点数据,然后才能使用它进行渲染。许多网格加载工具,例如 Open Asset Importer,将为您执行此修复。

还应注意,大多数网格不是立方体。大多数网格在绝大多数顶点上都是平滑的,只是偶尔会有不同的法线/纹理坐标等。因此,虽然这通常出现在简单的几何形状中,但实际模型很少有大量的顶点重复。

GL 3.x 和 D3D10

对于 D3D10/OpenGL 3.x 类硬件,可以避免执行修复并直接使用多个索引属性。但是,请注意,这可能会降低渲染性能。

以下讨论将使用 OpenGL 术语,但 Direct3D v10 及更高版本具有等效功能。

这个想法是从顶点着色器手动访问不同的顶点属性。不是直接发送顶点属性,而是传递的属性实际上是该特定顶点的索引。然后顶点着色器使用索引通过一个或多个缓冲区纹理访问实际属性。

属性可以存储在多个缓冲区纹理中或全部存储在一个中。如果使用后者,那么着色器将需要一个偏移量来添加到每个索引,以便在缓冲区中找到相应属性的起始索引。

可以通过多种方式压缩常规顶点属性。缓冲区纹理的压缩方式较少,仅允许相对有限数量的顶点格式(通过它们支持的图像格式)。

请再次注意,这些技术中的任何一种都可能降低整体顶点处理性能。因此,它应该只在内存最有限的情况下使用,在所有其他压缩或优化选项都已用尽之后。

OpenGL ES 3.0 也提供缓冲纹理。更高的 OpenGL 版本允许您通过SSBO而不是缓冲区纹理更直接地读取缓冲区对象,后者可能具有更好的性能特征。

于 2012-06-22T00:05:02.203 回答
5

我找到了一种方法,可以让你减少这种与其他答案中的一些陈述有点相反的重复(但并不特别适合这里提出的问题)。然而,它确实解决了我的问题,这个问题被认为是这个问题的重复。

我刚刚了解了插值限定符。特别是“平”。我的理解是,将 flat 限定符放在顶点着色器输出上只会导致挑衅顶点将其值传递给片段着色器。

这意味着对于此引用中描述的情况:

因此,如果您有一个立方体,其中每个面都有自己的法线,您将需要大量复制位置和法线数据。您将需要 24 个位置和 24 个法线,即使立方体只有 8 个唯一位置和 6 个唯一法线。

您可以有 8 个顶点,其中 6 个包含唯一法线,而忽略 2 个法线值,只要您仔细排序基元索引,以便“激发顶点”包含您要应用于整个面部的法线数据。

编辑:我对其工作原理的理解:

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

于 2018-10-16T07:50:21.957 回答