4

我目前正在为一个学校项目开发我的第一个 3D 游戏,游戏世界完全受到我的世界的启发(完全由立方体组成的世界)。我目前正在寻求提高尝试实现顶点缓冲区对象的性能,但我被卡住了,我已经实现了这个方法:Frustum culling, only drawexposed faces and distance culling 但我有以下疑问:

  1. 我目前在我的世界中有大约 2^24 个立方体,分成 1024 个 16*16*64 立方体的块,现在我正在做即时模式渲染,它适用于平截头体剔除,如果我每个块实现一个 VBO,做每次移动相机时我都必须更新那个 VBO(更新截锥体)?这对性能有影响吗?

  2. 我可以动态更改每个 VBO 的大小吗?还是我必须使每个都尽可能大(块完全充满对象)?

  3. 我是否必须将每个访问的块保留在内存中,或者我是否可以有效地删除该 VBO 并在需要时重新创建它。

4

2 回答 2

2
  1. 第一种天真的(不一定是坏的感觉)方法确实是根据平截头体和隐藏面剔除结果在每一帧更新 VBO。虽然这听起来很邪恶,但请记住,使用即时模式实际上做同样的事情(每帧将每个顶点发送到 GPU),但需要一百万次驱动程序调用(不要低估 a glVertex),而不仅仅是几个缓冲区函数和一个单次绘制调用。

    因此,使用 VBO(当然使用GL_DYNAMIC_DRAWor 甚至GL_STREAM_DRAW)很可能仍然比立即模式更快。不仅是可能的 GPU 存储,而且驱动程序调用数量的减少使得 VBO(或一般的顶点数组)比立即模式更快。

    稍后您还可以使用变换反馈实现一些更复杂的硬件剔除技术,因此您可以直接在 GPU 上进行剔除,而无需每帧将顶点数据发送到 GPU。

  2. 由于您在每帧更新整个缓冲区(因此应该调用glBufferData),因此调整大小绝对没有问题。只需glBufferData用不同的大小再次调用。

  3. 这取决于你有多少块。但是如果它们的数量变大,一些缓存技术(删除更远的 VBO、距离剔除、块)可能是个好主意。

于 2011-11-29T18:55:53.593 回答
2
  1. 每次更改相机截头体时都更改 VBO 可能不是一个好主意。持续缓冲数据的开销可能会超过绘制更少多边形所带来的任何性能提升。当它们完全移出截锥体时,你可能会更好地剔除整个 VBO。你最终会画出比严格必要的多的多边形,但这将被从 VBO 绘制比在立即模式下绘制快得多的事实所抵消。
  2. 您可以更改 VBO 的大小,但只能通过执行新调用,glBufferData如果您将数据发送到图形卡,这可能是一个昂贵的调用。
  3. 你最好不要把你创建的 VBO 的所有块都保存在内存中,那样很快就会失控。将您周围的环境留在记忆中,并在您离开时丢弃它们是您最好的选择。
于 2011-11-29T18:52:41.657 回答