- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在编写一个实验性应用程序,其中使用 VBO 渲染 100 个 16x16x16 立方体 block 。我这样做是因为有十几个人对 VBO 赞不绝口,并告诉我它的性能比我在实际的 Minecraft 风格游戏中使用的按 block 显示列表要好得多。
这是一个痛苦的过程,试图将许多只关注单个立方体/三角形的写得不好的教程改编成可以处理我需要的绘图量的东西。我仍然不相信 VBO 比显示列表更适合我的游戏。
在很大程度上,我最终调整了代码,以便我的交错 VBO 数据仅构建一次(当 block 加载时),然后每次 render
调用,缓冲区 ID 被绑定(bind)并调用 glDrawArrays
。
我正在慢慢增加这个实验性应用程序中的 block / block 的数量,以了解性能如何处理。在实际游戏中,它必须处理每个 block 中的 16x16x128 个 block ,最多加载 20x20 个 block 。其中大约 60% 将是渲染的实心 block ,因此可能有 800 万个 block 。使用我开始使用的显示列表方法,渲染没有太多问题。
但是,即使我现在的 VBO 渲染性能在可容忍的水平内,我也无法在不达到内存限制的情况下生成 10 个 block 的半径:
Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory
at java.nio.Bits.reserveMemory(Bits.java:658)
at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:123)
at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:306)
at org.lwjgl.BufferUtils.createByteBuffer(BufferUtils.java:60)
at org.lwjgl.BufferUtils.createFloatBuffer(BufferUtils.java:110)
at com.helion3.opengl.rendering.TextureQuadRenderer.<init>(TextureQuadRenderer.java:25)
at com.helion3.opengl.shapes.Chunk.<init>(Chunk.java:13)
at com.helion3.opengl.shapes.World.<init>(World.java:18)
at com.helion3.opengl.Game.start(Game.java:90)
at com.helion3.opengl.Launcher.main(Launcher.java:19)
我非常有信心我的缓冲区设置了所需的正确计数。我打电话:
BufferUtils.createFloatBuffer(
使用 192
每个立方体的 float (3 个顶点、3 个颜色、2 个纹理坐标乘以 6 个面,每个面 4 个顶点)乘以 4096
- block 测试中的 block 数。
现在在真正的游戏中,我不会渲染未暴露在空气中的 block 面 - 但即使我在这个测试应用程序中这样做,我仍然只渲染 16x16x16 block 。
如何更好地管理 VBO 内存?我的VBO测试app rendering code , chunk code
VBO 在什么时候会像大家所宣传的那样大放异彩?哈哈
附注我想我现在会深入实例化,看看这有什么帮助。
最佳答案
Now in the real game, I'm not rendering the block faces that aren't exposed to air - but even if I do that in this test application, I'm still only rendering 16x16x16 blocks.
这非常好。我只是提到这一点,因为首先也是最重要的,人们在编写 Minecraft 风格渲染器时常犯的一个错误是尝试发送 OpenGL 所有 block (如果他们渲染所有 block ,情况会更糟) )。相反,您应该确定哪些表面实际上可见,并且只将它们保留在 VBO 中。使用空间分割结构对此有所帮助。类似《我的世界》的世界充满了八叉树,它可以轻松存储实际的东西。 (这是供其他人在这里遇到此问答的)。
<小时/>要记住的另一件事是,由于所有内容都渲染为立方体,因此您不必保留数百万个(相同的)立方体,只需翻译即可。如果您使用实例,单个就足够了。
通过实例化,每个 block 只需要 4 个整数即可完整描述它(3 个表示位置,1 个表示表面,从 GL_TEXTURE_2D_ARRAY 加载)。整数更可取,因为它们的种类更小(唯一的缺点是旧的 GPU 无法有效地处理它们)。假设一个立方体代表 1 立方米。那么一个 16 位整数给你一个 (65536m)³ 的世界。此外,对于 Minecraft 风格的游戏,您几乎不需要超过 256 种表面。所以用8位整数来表示。然后,当您只考虑可见表面(即 block )时,许多体积不必驻留在 VBO 中。
这可以真正节省内存。从 32 位 float 转换为 16 位整数可以节省 50% 的内存。使用单个 8 位整数代替 3×32 位浮点颜色作为 Material 索引,可将内存需求减少到 1/12。
<小时/>为了进一步减少渲染负载,您可以利用世界上所有立方体都是并行的。这使得消除隐藏表面变得非常容易,甚至不进行处理:有 8 + 6 个主要方向可以用来查看立方体:8 个方向中共享一个角的 3 个面可见,6 个方向中只有您正在查看的表面直接可见。从当前的角度来看,确定每种情况适用的世界主要平面是相当容易的。因此,您有 14 个多维数据集基础模板的变体,并针对特定情况对每个子卷进行实例调用。八叉树再次帮助您选择哪些实例获得哪个变体。
<小时/>您应该考虑的另一件事是缓存一致性。多维数据集数据在 VBO 中的排列和对齐方式以及访问数据的顺序非常重要。一般来说,您希望数据能够很好地对齐和合并(尽管使用当前的多路径内存架构,分离的数据布局也可以提供相当好的性能)。然而,可以这么说,您的访问模式不应该“到处跳跃”。让您的访问保持良好的分组。这是显示列表优于 VBO 的主要原因:内容是恒定的,驱动程序可以将其内容重新排列成最佳对齐和有序的结构。您必须对此进行试验。
<小时/>为了让您了解当前最先进的游戏引擎的功能:DICE 最近的一份报告指出,在即将推出的“战地 4”游戏中,即使是最复杂的场景,生成的单个帧也不超过大约2000 次绘图 API 调用。这是一个非常低的数字。
关于java - 提高使用 VBO 时所需的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20448929/
我有一个依赖于包 B 的包 A。当包 A 中的代码运行并访问包 B 中的类时,包 B 的状态将被解析 (4),而不是 Activity (32) 和包 B 的激活器也没跑好。我认为 bundle B
这个问题在这里已经有了答案: How to remove the space between inline/inline-block elements? (41 个回答) 关闭 7 年前。
我正在尝试使用 Java OpenAL 库。我在导入名为 libsoft_oal.so 的 native 库时遇到问题。 Java OpenAL 依赖于 OpenAL 软实现。我尝试根据他们在 git
我正在尝试启动我的应用程序。是一个 unicorn +工头+sinatra的应用。 这是我的 config.ru 文件: require "rubygems" require "sinatra" Bu
我有一个下拉列表,其中包含一些从数据库表中检索的值,我想要的是当单击按钮时它应该只获得选项标签的中间值,但只有那些类名为“get_this”的选项标签并离开那些选项,如果他们没有这个类 预期输出:值
我有一个index.php文件,需要一个通用的head.php文件,head.php文件中有几个Javascript文件,当这样尝试时,代码在源代码中看起来很好,但文件却不是实际上对文档做任何事情。
有人能帮帮我吗? 我已经像这样运行了 imsmod: $ insmod /data/mm/mmdev.ko epoll_rate=100 但是我得到一个错误: insmod: init_module
是否有键盘快捷键或插件可以在 Notepad++ 中打开 PHP 所需或包含的文件?我知道,在 Dreamweaver 中,执行此操作的命令是 Ctrl+D,但我似乎无法在 Notepad++ 中找到
我已经用 js 设置了一个显示/隐藏 div,但我很难弄清楚如何一次显示一个 div。目前发生的情况是,除非我再次单击原始链接来关闭该 div,否则每个 div 都会显示。 http://www.li
当我尝试将未分配的辅助分片分配给节点时出现错误。 { "error": { "root_cause": [ { "type": "remote_transpor
我正在构建一个 C++ 应用程序,使用 Netbeans 6.9 作为我的 IDE。我有一个 C++ 库,它是一个纯 C 库的包装器。 我已将文件正确添加到项目中(使用添加库文件选项)。这是 g++
我是一名优秀的程序员,十分优秀!