假设我有5个实体(对象),方法Render()
。每个实体都需要在缓冲区中设置自己的顶点进行渲染。
以下两个选项中的哪一个更好?
glGenBuffer
创建的一个大的预分配缓冲区,每个实体将使用(缓冲区的id作为Render
方法的参数传递),将其顶点写入{{1}的缓冲区}。如果一个大缓冲区更好,如何使用适当的着色器和所有内容正确渲染此缓冲区中的所有顶点(来自所有实体)?
答案 0 :(得分:9)
只要具有一定的大小,就可以使用多个VBO。你想要避免的是有很多小的绘制调用,并且必须非常频繁地绑定不同的缓冲区。
缓冲区必须有多大才能避免过多的开销,这取决于很多因素,甚至不可能给出经验法则。发挥作用的因素包括:
通常,保留通常在单个顶点缓冲区中同时绘制的相似/相关对象是有意义的。
将所有内容放在一个缓冲区中似乎极端,实际上可能会产生负面影响。假设你有一个很大的世界",你只能在任何给定的帧中渲染一个小子集。如果你走到极端,一个巨大的缓冲区中包含所有顶点,那么每次绘制调用都需要GPU访问该缓冲区。根据体系结构以及缓冲区的分配方式,这可能意味着:
如果上述任何一个需要应用于一个非常大的缓冲区,但最终只使用它的一小部分来渲染一个帧,那么这些操作就会有很大的浪费。在具有VRAM的系统中,它还可以防止其他分配(如纹理)适合VRAM。
如果使用只能访问参数给出的缓冲区子集的调用来完成渲染,例如glDrawArrays()
或glDrawRangeElements()
,则驱动程序可能会避免使整个缓冲区GPU成为可能无障碍。但我不一定会指望这种情况发生。
答案 1 :(得分:1)
对于您拥有的每个实体,使用一个带有glGenBuffer
的VBO(顶点缓冲区对象)更容易,但它并不总是最好的事情,这取决于使用情况。但是,在大多数情况下,每个实体拥有1个VBO并不是一个问题,渲染很少受到影响。