需要一些帮助来实现带有视锥体剔除的 VBO
我目前正在为学校项目开发我的第一个 3D 游戏,游戏世界完全受到《我的世界》的启发(完全由立方体组成的世界)。我目前正在寻求提高尝试实现顶点缓冲区对象的性能,但我陷入困境,我已经实现了以下方法:视锥体剔除,仅绘制暴露的面和距离剔除,但我有以下疑问:
我目前我的世界中有大约 2^24 个立方体,分为 1024 个 16*16*64 立方体块,现在我正在进行立即模式渲染,如果我实现的话,它可以很好地与视锥体剔除配合使用每个块一个 VBO,每次移动相机(以更新视锥体)时是否都必须更新该 VBO?这对性能有影响吗?
我可以动态改变每个VBO的大小吗?或者我是否必须使每个 VBO 的大小尽可能最大(块完全充满对象)?。
我是否必须将每个访问过的块保留在内存中,或者我是否可以有效地删除该 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:
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?
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)?.
Would I have to keep each visited chunk in memory or could I efficiently remove that VBO and recreated it when needed.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
glBufferData
进行新的调用来更改,如果您要将数据发送到显卡,这可能是一个昂贵的调用。glBufferData
which can be an expensive call if you're sending the data to the graphics card.第一个天真的(不一定是坏的感觉)方法确实是根据视锥体和隐藏面剔除结果更新每一帧的 VBO。尽管这听起来很邪恶,但请记住,使用立即模式实际上会做同样的事情(每帧将每个顶点发送到 GPU),但会调用一百万次驱动程序调用(不要低估
glVertex
)只需几个缓冲区函数和一个绘制调用。因此,使用 VBO(当然,使用
GL_DYNAMIC_DRAW
甚至GL_STREAM_DRAW
)很可能仍然比立即模式更快。不仅是可能的 GPU 存储,而且驱动程序调用数量的减少使得 VBO(或一般的顶点数组)比立即模式更快。</p>稍后您还可以使用变换反馈来实现一些更复杂的硬件剔除技术,这样您就可以直接在 GPU 上进行剔除,而无需每帧将顶点数据发送到 GPU。
由于您每帧更新整个缓冲区(因此应该调用
glBufferData
),因此调整大小绝对没有问题。只需使用不同的大小再次调用glBufferData
即可。这取决于你有多少块。但如果它们的数量变大,一些缓存技术(删除较远的 VBO、距离剔除、块)可能是个好主意。
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 evenGL_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.
Since you update the whole buffer each frame (and therefore should call
glBufferData
) anyway, resizing is absolutely no problem. Just callglBufferData
again with a different size.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.