我一直在尝试一下,现在可以使用
在屏幕上渲染大约300万个GL_QUADSglDrawArrays(GL_QUADS, 0, nVertexCount);
我还使用多个缓冲,循环通过18个顶点缓冲对象,每个顶点有100万个顶点。使用存储在堆上的压缩数据和简单计算来计算每个顶点位置。我用
ptr = (float*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
和
glUnmapBuffer(GL_ARRAY_BUFFER);
每个帧将每个顶点写入缓冲区对象。当缓冲区对象已满时,我取消映射它,调用glDrawArrays,然后绑定并映射下一个VBO以传输更多顶点数据。当所有18个被使用时,我在逻辑上绑定第一个并重新开始。
根据我的经验,使用VBO的映射几乎是使用堆数组的顶点数据的两倍。我怎么知道?因为,由于我渲染了3百万个GL_QUADS,因此帧速率明显低于30 fps。我只能用眼睛观察VBO的帧速率是两倍。
我还做了观察,在每个填充的顶点缓冲区对象上连续两次调用glDrawArrays(导致渲染两倍的四边形,但一旦流动顶点数据的努力) - 仅比渲染慢得多只有一次。因此,我认为主要的瓶颈是将顶点数据流式传输到顶点缓冲区对象(2 GHz双核处理器占用了60%!)。
现在每个顶点需要3个浮点数和2个浮点数用于纹理坐标。 (总共20个字节)。我想我可以将这个数量缩短为3 GL_SHORT加上2 GL_SHORT纹理坐标。使用转换矩阵(总共5个字节),但这只会加速4倍。 (不知怎么,sizeof(GL_SHORT)在我的系统上给出4,所以我也不确定。)
无论如何,那里有游戏,甚至已经很老了但是每帧都会在屏幕上呈现超过3百万个基元(并且它们不可避免地必须流式传输这些顶点,因为没有GPU可以保持这样很多数据)并且仍然可以获得超过100 fps的体面帧速率!
我确信,我仍然缺少这个过程中的一些重点,但我无法弄清楚它是什么。有什么建议吗?
编辑: 这些是粒子系统中的松散四边形。 (或者更确切地说,因为每个人可能最终都有不同的纹理(纹理取自单个纹理的子纹理,所以没有广泛的绑定;)))
答案 0 :(得分:2)
我确信,我仍然缺少这个过程中的一些重点
点应该是我是否需要绘制3 MB的三角形?,而不是如何打破硬件限制?
您应该知道的限制应该是硬件。传输速率,GPU时钟和内存时钟是没有更新硬件时无法覆盖的特性。实际上,您应该尝试有效地使用当前的硬件。
据我所知,你需要在渲染时更新顶点缓冲区;所以你映射缓冲区对象,更新数据,取消映射和渲染。我想你是重复做的。在这种情况下,您必须考虑从CPU到GPU的传输速率;你能减少渲染场景所需的数据吗?也许内插关键的顶点位置?
例如,如果我需要渲染地形,我可以发送数十亿个三角形来渲染完美的地形。但我肯定只使用最重要的结果就可以达到相同的效果。使用较少的三角形而不会扭曲好结果,让我能够做得越来越多。
在1920x1080有2 MB的像素......我需要使用2 MB的三角形来绘制它?也许片段着色器会表现得更好。
有许多技术用于减少处理负载(包括CPU和GPU)和传输速率:
答案 1 :(得分:1)
实际上你可以做很多事情(或者为了获得更多的吞吐量而做的事情)。 我只是略读一些,因为这可以(并且确实)填写(或更多)书籍。
我可以推荐这些书籍作为主题的一个条目:
答案 2 :(得分:1)
每个顶点位置都是使用存储在堆上的压缩数据和简单计算来计算的。
也许顶点或几何着色器可以代替吗?
无论如何,那里有游戏,甚至已经很老了但是每帧都会在屏幕上呈现超过3百万个基元(并且它们不可避免地必须流式传输这些顶点,因为没有GPU可以保持这样很多数据)
3000000 * 20 bytes = 60 megabytes
即使是较旧的GPU也很容易接触到。