我需要知道如何渲染许多不同的3D模型,这些模型会根据每一帧(动画模型)更改其几何形状,不要重复模型和纹理。
我携带所有模型,并为每个模型创建一个"对象"模型类。
渲染它们的最佳方法是什么?
- 为每个 3D 模型使用 1 个 VBO(英语:1 个 VCO)
- 对所有模型使用单个 VBO(完全不同,我认为此选项是不可能的)
我使用OpenGL 3.x或更高版本,C++Windows上。
TL;DR - 在渲染性能方面没有灵丹妙药
为什么?这取决于获取数据,转换数据,将其推送到GPU然后使屏幕上的像素闪烁的复杂过程。因此,不是"一种最佳方法",而是出现了一些通常可以提高性能的准则。
- 将所有必要的数据保存在GPU上(因为离屏幕越近,电子必须走
:)
的方式就越短)
在 - 帧之间向 GPU 发送尽可能少的数据
- 不要在CPU和GPU之间不必要地同步(这就像试图在平行轨道上运行两个高速列车,但坚持将它们减慢到每隔一段时间就可以通过窗口传递某些东西的程度),
现在,很明显,如果你想有一个会改变的模式,你不能有蛋糕吃它。你必须做出权衡。简而言之,动态对象的渲染速度永远不会像静态对象那样快。那么,你应该怎么做呢?
- 提示GPU有关数据使用(
GL_STREAM_DRAW
或GL_DYNAMIC_DRAW
) - 这应该保证最佳的内存安排。 - 不要使用交错缓冲区将静态顶点属性与动态顶点属性混合 - 例如,如果划分内存,则可以批量更新几何图形,保持纹理坐标不变。
- 尝试纯粹在 GPU 上做尽可能多的事情 - 使用计算着色器和转换反馈,很可能将整个动画数据存储为缓冲区本身并在 GPU 上计算,避免昂贵的同步。
最后但并非最不重要的一点是,始终仔细衡量您的更改对绩效的影响。盲目行事无济于事。准确彻底地测量(甚至像着色器编译时间这样的东西有时也很重要!然后,即使你通过反复试验,也有希望你会到达某个地方。
特别要解决你的一个观点;无论是一个大的VBO还是几个较小的VBO并不重要,但是一个巨大的VBO可能会在内存中出现问题。您仍然可以更新其中的某些部分,最重要的是其中的内存排列。