顶点批处理(几何组)和最大VBO(顶点缓冲区)大小

时间:2016-02-03 10:52:39

标签: opengl vbo vertex-buffer

我做了很多关于将顶点数据收集到通常称为批次的组中的方法的研究。

这里有关于这个主题的两篇主要有趣的文章:

https://www.opengl.org/wiki/Vertex_Specification_Best_Practices

http://www.gamedev.net/page/resources/_/technical/opengl/opengl-batch-rendering-r3900

第一篇文章解释了如何操作VBO的最佳实践(最大尺寸,格式等)。

第二个介绍了如何使用批处理管理顶点内存的简单示例。根据作者的说法,每批HAS TO都包含一个VBO实例(加上一个VAO),他强烈坚持VBO的最大大小介于1Mo(1000000字节)到4Mo(4000000字节)之间的事实。第一篇文章提出同样的建议。我引用“根据一个nVidia文档,1MB到4MB是一个不错的尺寸。驱动程序可以更容易地进行内存管理。对于所有其他实现,如ATI / AMD,Intel,SiS应该是相同的情况。”

我有几个问题:

1)上面提到的最大字节大小是绝对规则吗?分配比4Mo更重要的字节大小的VBO(例如10 Mo)是不是很糟糕?

2)我们如何处理总顶点字节大小大于4Mo的网格?我是否需要将几何体分成几批?

3)批次是否不可避免地将属性存储为唯一的VBO,或者可以将多个批次存储在单个VBO中? (这是两种不同的方式,但第一种似乎是正确的选择)。你同意吗?

根据作者的说法,每个批处理一个唯一的VBO,最大大小在1到4 Mo之间,整个VBO HAS TO只包含共享相同材料和转换信息的顶点数据)。因此,如果我必须使用不同的材质批处理其他网格(因此顶点不能与现有的网格合并),我必须使用新的vbo instanciated创建一个新的批处理。

所以根据作者我的第二种方法是不正确的:不建议将几个批次存储到一个VBO中。

1 个答案:

答案 0 :(得分:1)

  

上面提到的最大字节大小是绝对规则吗?分配比4Mo更重要的字节大小的VBO(例如10 Mo)是不是很糟糕?

没有

这是一个(非常)旧的信息,在现代硬件上不一定有效。

导致4MB建议的问题是驱动程序能够管理内存。如果你分配的内存比GPU多,那么它需要进出一些页面。如果对缓冲区对象使用较小的块,则驱动程序更容易选择整个缓冲区进行分页(因为它们目前尚未使用)。

然而,这并不重要。您可以为性能做的最好的事情是避免完全超出内存限制。进出内容会伤害表现。

所以不要担心。请注意,我删除了这个"建议"来自Wiki。

  

所以根据作者我的第二种方法是不正确的:它并不建议将几个批次存储到一个VBO中。

我认为你混淆了#34;批次"使用" mesh"。但这完全可以理解;你读过的那份文件的作者似乎也没有意识到这一点。

为了讨论的目的,一个"网格"是一个使用单个rendering command呈现的东西,它在概念上与您要呈现的其他内容分开。网格以某种状态呈现。

A"批次"指的是可以使用单独的渲染命令渲染的一个或多个网格。但是,为了提高性能,您可以使用技术允许使用相同的渲染命令渲染所有内容。所有批次都是。

"配料"采用一系列网格并使其成为批处理的过程。 Instanced rendering是一种批量形式;每个实例都是一个单独的"网格",但是你通过一次渲染调用渲染它们。他们使用实例计数来获取每个实例的状态数据。

批处理采用多种形式,而不是实例化渲染。批处理经常发生在艺术家的层面。虽然建模师/纹理艺术家可能想要将角色分成不同的部分,每个部分都有自己的纹理和材质,但是图形程序员告诉他们将它们保持为可以使用相同纹理/材质渲染的单个网格。

使用更好的硬件,可以减少批处理规则。使用array textures,您可以为每个网格物体提供一个特定的ID,用于挑选它在获取纹理时使用的数组层。这允许艺术家给这些角色更多的纹理变化,而不会将批量分成多个渲染调用。 Ubershaders是另一种形式,着色器使用该ID来决定如何进行照明,而不是(或除了)纹理提取。

你引用的人正在谈论的那种批处理是......好吧,很困惑。

  

你怎么看?

嗯,坦率地说,我认为第二个链接中的人应该被忽略。他的代码的第一行:class Batch sealed不是有效的C ++。它是一些C ++ / CX微软的发明,在这种情况下很好。但是他试图将其作为纯粹的C ++传递出来;那不好

我的代码质量也没有给他留下特别深刻的印象。他自相矛盾。例如,他谈到了能够分配合理大小的内存块的重要性,以便驱动程序可以更自由地移动内容。但他的GuiVertex课程可怕的臃肿。它使用完整的16个字节,四个浮点数,仅用于颜色。 4个字节(作为规范化的无符号整数)就足够了。类似地,他的纹理坐标是浮点数,当短路(作为无符号的归一化整数)对于他的用例来说是好的。这会将他的每顶点成本从32个字节减少到10个;这不仅仅是3:1的减少。

当您使用合理大小的顶点数据时,

4MB会更长。最好的部分?他链接到tells you to do exactly this.的OpenGL Wiki页面但是他没有这样做。

更不用说,他显然已经为GUI编写了这个批处理管理器(正如他的GuiVertex类型所暗示的那样)。然而,GUI可能是游戏开发中最少批处理友好的渲染场景。您经常需要更改状态,如绑定纹理,当前程序(从纹理读取或不读取),混合模式,剪刀框等。

现在使用现代GPU,有一些方法可以使GUI渲染器更加批处理。但他从不谈论他们。他没有提到使用gl_ClipDistance作为一种使用每顶点数据做剪刀盒的方法的技术。他没有谈论ubershader的使用,他的顶点格式也没有提供允许这样做的ID。

如前所述,批处理是指对象之间没有状态变化。但他将完全集中在顶点状态上。他没有谈论纹理,程序等。他没有谈论允许多个对象成为同一批次的一部分的技术,同时仍然有单独的变换。

他的课程不能用于批量任何不可能只是单个网格的东西。