当前位置: 首页 > 知识库问答 >
问题:

改进使用VBOs时所需的内存

王兴庆
2023-03-14

我一直在编写一个实验应用程序,其中我使用VBO渲染了100块16x16x16立方体。我之所以这么做,是因为有十几个人赞扬了超能力VBO,并告诉我它的性能比我在实际的Minecraft风格游戏中使用的每块显示列表要好得多。

这是一个痛苦的过程,试图将许多只关注单个立方体/三角形的编写糟糕的教程改编成能够处理我需要的绘图量的内容。我仍然不相信VBO比显示列表更适合我的游戏。

在大多数情况下,我最终调整了代码,使我的交错VBO数据只构建一次(当块加载时),然后每次渲染调用,缓冲区ID被绑定,glDrawArray被调用。

我正在慢慢增加这个实验应用程序中块/块的数量,以了解性能如何处理。在实际游戏中,它必须处理每个块中的16x16x128个块,最多加载20x20个块。其中大约60%是渲染的实体块,所以可能800万块。使用我开始使用的显示列表方法,这没有太大问题。

然而,即使我现在的VBO渲染性能在可容忍的水平内,我也不能在不达到内存限制的情况下生成10块的半径:

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每个立方体(3个顶点,3种颜色,2个纹理和弦乘以6个面,每个面4个顶点)乘以4096-块的数量组块测试。

现在在真实的游戏中,我不会渲染没有暴露在空气中的块面-但即使在这个测试应用程序中这样做,我仍然只渲染16x16x16块。

如何更好地管理VBO内存?我的VBO测试应用程序呈现代码,区块代码

在哪一点上,VBO会像每个人所宣传的那样闪闪发光?英雄联盟

P. S.我想我现在要潜入实例化,看看这有什么帮助。

共有1个答案

缪茂勋
2023-03-14

现在在真实的游戏中,我不会渲染没有暴露在空气中的块面-但即使在这个测试应用程序中这样做,我仍然只渲染16x16x16块。

那太好了。我只是提到这一点,因为首先也是最重要的是,人们在编写Minecraft风格的渲染器时犯的一个常见错误是试图将所有的块发送给OpenGL(如果它们都渲染的话,情况会更糟)。相反,您应该确定哪些曲面实际上是可见的,并且只将这些曲面保留在VBO中。在这里,使用空间细分结构很有帮助。一个像地雷船一样的世界散发着八叉树的气味,它可以简单地存储实际的东西。(这是给遇到这个问题的其他人的。)

另一件需要记住的事情是,由于所有内容都呈现为立方体,所以您不必保留数百万(相同的)立方体,只需翻译即可。如果使用实例,一个实例就足够了。

使用实例化,每个块只需4个整数即可对其进行完整描述(3个用于位置,1个用于曲面,从GL_纹理_2D_数组加载)。整数更可取,因为它们有更小的种类(唯一的缺点是,旧的GPU不能有效地处理它们)。假设一个立方体代表1m³。然后,一个16位整数给出一个(65536m)³的世界。此外,你几乎不需要超过256种表面为一个雷霆风格的游戏。所以用一个8位整数来表示。然后,当你只考虑可见的表面,那么块,很多你的体积不必驻留在VBO中。

这可以是一个真正的内存保护程序。从32位浮点数到16位整数节省了50%的内存。使用单个8位整数作为材质html" target="_blank">索引,而不是3×32位浮点颜色,将内存需求减少到1/12。

为了进一步减少渲染负载,可以利用世界上所有立方体都是平行的这一点。这使得消除隐藏曲面(即使在处理过程中)变得非常容易:有8个6个主要方向可以查看立方体:8个方向可以看到共享一个角的3个面,6个方向只能看到直接查看的曲面。从目前的观点来看,确定世界上每种情况适用的主平面相当容易。因此,您有14种多维数据集基础模板变体,并针对特定情况对每个子卷进行实例调用。八叉树再次帮助您选择哪些实例获得哪种变体。

您应该考虑的另一件事是缓存一致性。多维数据集的数据在VBO中的排列和对齐方式以及访问顺序是非常重要的。通常,您希望数据能够很好地对齐和合并(尽管在当前的多路径内存体系结构中,单独的数据布局也可以提供相当好的性能)。不过,可以说,您的访问模式不应该“到处跳跃”。保持访问分组良好。这是显示列表优于VBO的主要原因:内容是恒定的,驱动程序可以将其内容重新排列为最佳对齐和有序的结构。你得试试这个。

为了让您了解当前最先进的游戏引擎的功能:DICE最近的一份报告指出,在即将推出的“战场4”游戏中,即使是最复杂的场景,单帧也只由不超过2000个绘图API调用生成。这个数字真的很低。

 类似资料:
  • 我试图使用Android Apache HttpClient做一个POST,但它返回错误411内容长度必需。这是代码。 我已经尝试添加行:- 但我得到了一个“组织”。阿帕奇。http。ProtocolException:内容长度标头已出现“错误”。这必须意味着HttpClient已经在发送内容长度。不幸的是,我无法访问服务器端。知道为什么会返回这些错误吗?

  • 如何在jmeter(负载测试)中模拟多个会话(用户)在网站上长时间停留(例如超过15分钟)并发出多个请求

  • 我计划写一个3D游戏,将使用VBOs渲染。例如,假设地形是一组平铺,它们的顶点都在同一个VBO中。玩家应该能够滚动浏览瓷砖,并且在任何时候都只能看到瓷砖的一部分。 我想在这些瓷砖上执行截锥剔除。我已经在截头体剔除的数学部分找到了一些来源,但我不确定如何用VBO实现这一点-人们是在顶点着色器中以某种方式实现的,还是仅仅调用渲染函数来绘制VBO的子集。

  • 问题内容: Python程序是否有办法确定当前正在使用多少内存?我已经看到了有关单个对象的内存使用情况的讨论,但是我需要的是该过程的总内存使用情况,以便可以确定何时需要开始丢弃缓存的数据。 问题答案: 这是适用于各种操作系统(包括Linux,Windows 7等)的有用解决方案: 在我当前使用psutil 5.6.3安装的python 2.7中,最后一行应为 相反(API发生了变化)。 注意:如果

  • 我正在努力检索基于内容所有者的YouTube分析数据。从这次讨论(获取当前用户的YouTube内容所有者id)中,我了解到我需要查询youtubePartner.contentOwners.list(fetchmine=true)来获取内容所有者信息,其中的Id将被找到。 我纠结的是,当我调用youtubepartner . content owners . list(fetch mine = t

  • 问题内容: 我想知道如何更改URL而不重定向,就像在我们的网站http://dekho.com.pk/ads-in- lahore 上那样, 当我们单击选项卡时url会更改,但是页面完全重新加载。在上还有其他问题,表明这是不可能的,但我想知道上述网站是如何实现的。谢谢 问题答案: 用途: