选择顶点缓冲区类型有哪些常用指南?我们什么时候应该使用隔行扫描缓冲区来处理顶点数据?什么时候我们应该使用索引数组和直接顶点数据?
我正在寻找一些常见的quidelines - 在某些情况下,其中一个或相反的更适合,但并非所有情况都很容易解决.在针对性能时,应该考虑选择顶点缓冲区格式?
还欢迎链接到该主题的Web资源.
Kil*_*nDS 17
首先,您可以在OpenGL wiki上找到一些有用的信息.其次,如果有疑问,可以对这个有一些经验法则,但经验可能因数据集,硬件,驱动程序......而异.
我几乎总是默认使用顶点缓冲区的索引方法.其主要原因是所谓的变换后缓存.它是在图形管道的顶点处理阶段之后保留的缓存.本质上,它意味着如果您多次使用顶点,则很有可能达到此缓存并且能够跳过顶点计算.有一个条件甚至命中这个缓存,那就是你需要使用索引缓冲区,没有它们就无法工作,因为索引是这个缓存密钥的一部分.
此外,您可能会节省存储空间,索引可以尽可能小(1个字节,2个字节),您可以重用完整的顶点规范.假设一个顶点和所有属性总共约30个字节的数据,你可以分享这个顶点,比如2个多边形.使用索引渲染(2字节索引),这将花费您2*index_size+attribute_size = 34 byte.使用非索引渲染,这将花费您60个字节.通常,您的顶点将被共享两次以上.
基于索引的渲染总是更好吗?不,可能会出现情况更糟的情况.对于非常简单的应用程序,设置基于索引的数据模型可能不值得代码开销.此外,当您的属性不是通过多边形共享时(例如,正常的每个多边形而不是每个顶点),可能根本没有顶点共享,IBO不会带来好处,只会产生开销.
除此之外,虽然它启用了转换后的缓存,但它确实使通用内存缓存性能更差.因为你相对随机地访问属性,你可能会有更多的缓存未命中和内存预取(如果这将在GPU上完成)将无法正常工作.因此,如果你有足够的内存并且顶点着色器非常简单,那么非索引版本的性能优于索引版本.
这个故事有点微妙,我认为它归结为权衡属性的某些属性.
让我们看看通过索引可以得到什么。每个重复的顶点(即具有“平滑”中断的顶点)将减少您的花费。每个奇异的“边缘”顶点都会使您花费更多。对于基于真实世界且相对密集的数据,一个顶点将属于许多三角形,因此索引将加快它的速度。对于程序生成的任意数据,直接模式通常会更好。
索引缓冲区还给代码增加了其他复杂性。
这里的主要区别实际上是基于一个问题“ 我是否只想更新一个组件? ”。如果答案是肯定的,那么您就不应该交错,因为任何更新都将耗资巨大。如果不是,则使用交错缓冲区可以改善引用的局部性,并且通常在大多数硬件上都更快。