首页 文章

使用多个索引渲染网格

提问于
浏览
51

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

2 回答

  • 1

    在最普遍的意义上,没有 . OpenGL和Direct3D每个顶点只允许一个索引;索引从每个顶点数据流中提取 . 因此,每个独特的组件组合都必须有自己独立的索引 .

    因此,如果你有一个立方体,每个面都有自己的法线,你需要经常复制位置和普通数据 . 你需要24个位置和24个法线,即使立方体只有8个独特的位置和6个独特的法线 .

    您最好的选择就是接受您的数据会更大 . 很多模型格式都会使用多个索引;在使用它进行渲染之前,您需要修复此顶点数据 . 许多网格加载工具(如Open Asset Importer)将为您执行此修复 .

    GL 3.x和D3D10

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

    以下讨论将使用OpenGL术语,但Direct3D v10及更高版本具有相同的功能 .

    我们的想法是从顶点着色器手动访问不同的顶点属性 . 传递的属性实际上是该特定顶点的索引,而不是直接发送顶点属性 . 然后,顶点着色器使用索引通过一个或多个buffer textures来访问实际属性 .

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

    可以通过多种方式压缩常规顶点属性 . 缓冲区纹理具有较少的压缩方式,只允许相对较小的压缩方式limited number of vertex formats (via the image formats they support).

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

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

  • 65

    我发现了一种允许你减少这种重复的方法,这种重复与其他答案中的一些陈述相反(但并不特别适合这里提出的问题) . 然而它确实解决了my question,这被认为是这个问题的重复 .

    我刚刚了解了Interpolation qualifiers . 具体来说"flat" . 我的理解是,将平坦限定符放在顶点着色器输出上只会导致provoking vertex将其值传递给片段着色器 .

    这意味着针对此报价中描述的情况:

    因此,如果你有一个立方体,每个面都有自己的法线,你需要经常复制位置和普通数据 . 你需要24个位置和24个法线,即使立方体只有8个独特的位置和6个独特的法线 .

    您可以有8个顶点,其中6个包含唯一法线,并且忽略2个正常值,只要您仔细排序基元索引,使“引发顶点”包含要应用于整个面的常规数据 .

    编辑:我对它是如何工作的理解:

    enter image description here

    enter image description here

    enter image description here

    enter image description here

相关问题