需要一些帮助来实现带有视锥体剔除的 VBO

发布于 2024-12-19 03:57:56 字数 428 浏览 2 评论 0原文

我目前正在为学校项目开发我的第一个 3D 游戏,游戏世界完全受到《我的世界》的启发(完全由立方体组成的世界)。我目前正在寻求提高尝试实现顶点缓冲区对象的性能,但我陷入困境,我已经实现了以下方法:视锥体剔除,仅绘制暴露的面和距离剔除,但我有以下疑问:

  1. 我目前我的世界中有大约 2^24 个立方体,分为 1024 个 16*16*64 立方体块,现在我正在进行立即模式渲染,如果我实现的话,它可以很好地与视锥体剔除配合使用每个块一个 VBO,每次移动相机(以更新视锥体)时是否都必须更新该 VBO?这对性能有影响吗?

  2. 我可以动态改变每个VBO的大小吗?或者我是否必须使每个 VBO 的大小尽可能最大(块完全充满对象)?。

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

I'm currently developing my first 3D game for a school project, the game world is completely inspired by minecraft (world completely made out of cubes). I'm currently seeking to improve the performance trying to implement vertex buffer objects but I'm stuck, I already have this methods implemented: Frustum culling, only drawing exposed faces and distance culling but I have the following doubts:

  1. I currently have about 2^24 cubes in my world, divided in 1024 chunks of 16*16*64 cubes, right now I'm doing immediate mode rendering, which works well with frustum culling, if I implement one VBO per chunk, do I have to update that VBO each time I move the camera (to update the frustum)? Is there a performance hit with this?

  2. Can I dynamically change the size of each VBO? Or do I have to make each one the biggest possible size (the chunk completely filled with objects)?.

  3. Would I have to keep each visited chunk in memory or could I efficiently remove that VBO and recreated it when needed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

煞人兵器 2024-12-26 03:57:56
  1. 每次更改相机视锥体时都更改 VBO 不太可能是一个好主意。连续缓冲数据所带来的开销可能会超过绘制更少的多边形所带来的任何性能提升。当 VBO 完全移出视锥体时,您可能会更好地剔除整个 VBO。您最终会绘制比严格需要的更多的多边形,但是从 VBO 中绘制比在即时模式中绘制要快得多这一事实足以平衡这一点。
  2. 您可以更改 VBO 的大小,但只能通过对 glBufferData 进行新的调用来更改,如果您要将数据发送到显卡,这可能是一个昂贵的调用。
  3. 您最好不要将创建 VBO 的所有块保留在内存中,否则很快就会失控。最好的选择是记住周围的环境,并在离开时丢弃它们。
  1. Altering the VBO every time you change the camera frustrum is not likely to be a good idea. The overhead from continuously buffering the data would probably outweigh any performance gains you would get from drawing fewer polygons. You would probably be better off culling entire VBOs when they move entirely out of the frustrum. You'll end up drawing more polys than are strictly necessary, but that will be more than balanced out by the fact that drawing from a VBO is drastically faster than drawing in immediate mode.
  2. You can change the size of a VBO, but only by doing a new call to glBufferData which can be an expensive call if you're sending the data to the graphics card.
  3. You would be best off not keeping all chunks you have created a VBO for in memory, that will quickly get out of hand. Keeping your immediate surroundings in memory, and discarding them when you move away is your best bet.
喜爱皱眉﹌ 2024-12-26 03:57:56
  1. 第一个天真的(不一定是坏的感觉)方法确实是根据视锥体和隐藏面剔除结果更新每一帧的 VBO。尽管这听起来很邪恶,但请记住,使用立即模式实际上会做同样的事情(每帧将每个顶点发送到 GPU),但会调用一百万次驱动程序调用(不要低估 glVertex)只需几个缓冲区函数和一个绘制调用。

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

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

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

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

  1. The first naive (not neccessarily in a bad sense) approach would indeed be to update the VBO every frame based on the frustum and hidden face culling results. Although this may sound evil, keep in mind that using immediate mode does actually the same thing (send each vertex to GPU every frame) but with a million of driver calls (don't underestimate a glVertex) instead of just a few buffer functions and a single draw call.

    So using VBOs (with a usage of GL_DYNAMIC_DRAW or even GL_STREAM_DRAW, of course) will most probably still be faster than immediate mode. It is not only the possible GPU storage but also the reduced number of driver calls that make VBOs (or vertex arrays in general) faster than immediate mode.

    Later on you can also implement some more sophisticated hardware culling techniques, using transform feedback, so you do culling directly on the GPU and don't need to send the vertex data to the GPU each frame.

  2. Since you update the whole buffer each frame (and therefore should call glBufferData) anyway, resizing is absolutely no problem. Just call glBufferData again with a different size.

  3. It depends how many chunks you have. But if their number gets larger, some caching technique (delete VBOs of farther away, distance culled, chunks) may be a good idea.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文