Opengl 使用多个索引渲染网格

Opengl 使用多个索引渲染网格,opengl,opengl-es,webgl,direct3d,vulkan,Opengl,Opengl Es,Webgl,Direct3d,Vulkan,我有一些顶点数据。位置、法线、纹理坐标。我可能是从.obj文件或其他格式加载的。也许我在画一个立方体。但每个顶点数据都有自己的索引。我可以使用OpenGL/Direct3D渲染此网格数据吗?在最一般的意义上,不可以。OpenGL和Direct3D只允许每个顶点有一个索引;索引从每个顶点数据流中提取。因此,每个唯一的组件组合都必须有自己的单独索引 因此,如果你有一个立方体,每个面都有自己的法线,你需要大量复制位置和法线数据。您将需要24个位置和24条法线,即使立方体只有8个唯一位置和6条唯一法线

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

在最一般的意义上,不可以。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版本允许您通过缓冲区纹理而不是缓冲区纹理更直接地读取缓冲区对象,缓冲区纹理可能具有更好的性能特征。

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

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

这意味着对于本报价中描述的情况:

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

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

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


有一篇关于这方面的文章(第21章-可编程顶点拉伸),但它不能直接访问。尽管如此。之所以如此缓慢,是因为它不是按顺序访问缓冲区吗?@Samik:任何类型的索引访问都将是非顺序的;这就是重点。性能差异通常在硬件实际支持顶点拉取的硬件中发挥作用。AMD基于GCN的体系结构确实如此不需要,因此他们必须基于VAO修补顶点着色器,以创建硬件顶点拖动的错觉。因此,自己手动操作可能不会降低速度。您不需要缓冲纹理。您可以使用常规纹理。换句话说,您可以在DirectX9、OpenGL 2.1中执行此操作。此处的实时示例说明:not saying你应该这样做。只是这是完全可能的。@deqyra:“根据三角形的不同,它必然有不同的法线”为什么?两个三角形之间的锐边和平滑边之间的区别不是三角形之间的角度,而是边顶点处的法线是否不同。如果它们相同,则是平滑边(或一个近似值)。而且大多数模型都是平滑的。那么,你实际上是如何做到的呢?你的索引数据必须是什么样子的?你如何为VS提供位置和法线以便它可以做到这一点?我仍在自己实现它。我将用我的理解的基本示例更新我的答案。在图像中发布文本会使阅读和使用变得困难,所以不要这样做那就是。你可以使用图像,只需将文本放在帖子的文本中。此外,你不断混淆“位置”和“顶点”的术语;当涉及到图形时,它们是不可互换的。第三,你的索引顺序没有一致的缠绕顺序(至少,我说不出来)最后,这个技巧只适用于立方体,并且只适用于位置+法线;如果你需要每个面都有纹理坐标,这将不会有帮助