在我的程序中我想绘制很多领域。 首先我创建顶点,球体的索引然后将它们绑定到voa / vbo / ibo。 之后我创建了1000个随机模型矩阵。 现在我有两种绘制网格的方法。
glDrawElements
的ModelMatrices列表循环1000次。矩阵
MVP在CPU上计算并发送到着色器,就像统一一样。glDrawElementsInstanced
打电话一次。在测试程序中我绘制了1000个球体(大约20milions顶点) 当我使用第一种方法时我得到27FPS左右而第二次降低性能达到19FPS。理论上第二种方法应该达到比第一种更好的性能。
这是代码。
我认为瓶颈是顶点着色器(VP * ModelMatrix)
中的这种倍增,因为它需要为每个(网格中的顶点)* 1000完成。
什么可以升级,我做错了什么?
答案 0 :(得分:10)
实例化并不总是一场胜利。这是您必须分析的优化类型,以确定它是否值得。
一般来说,如果你渲染了很多实例(1000是相当多,但还不够。想想10,000),实例化是一个胜利,它包含适度数量的顶点(20,000可能太多了。看看更多-3000左右)。此外,您的每个实例数据不必要地大;当你可以很容易地使用向量和四元数时使用矩阵。
实例化的目的是减少 CPU开销。特别是CPU每次绘制调用开销和状态变化。总共有2000万个顶点,1000个绘制调用和状态变化的CPU开销不是你最大的问题。
答案 1 :(得分:5)
由于你有旋转不变的球体,你可以用一个简单的平移vec3替换你的矩阵(可能用w =均匀比例?)。我不确定它会改变什么,但是,你很少受到ALU约束。但是20M顶点非常多。
1000个绘制调用/帧完全在PC可以处理的范围内(通常应该<3000),这解释了简单版本不太慢的事实。
至于实例的糟糕表现,我真的不知道,但我怀疑它与你的高达20k顶点/网格有关。 Instancing是针对相当小的网格而设计的,因此GPU可能无法很好地处理。您可以尝试与Vsync关闭较小的网格(200个顶点)进行比较吗?我很好奇。