OpenGL低级性能问题

dec*_*iar 19 opengl optimization performance sdl opengl-3

与任何优化问题一样,这个主题受到很多打击,但我找不到我想的东西.

很多教程,甚至SO问题都有类似的提示; 一般涵盖:

  • 使用GL面部剔除(OpenGL功能,而不是场景逻辑)
  • 仅向GPU发送1个矩阵(projectionModelView组合),因此将每个顶点的MVP计算减少到每个模型一次(应该如此).
  • 使用交错顶点
  • 最小化尽可能多的GL调用,在适当的情况下进行批处理

可能还有一些/很多其他人.我(出于好奇的原因)在我的应用程序中使用几个顶点缓冲区渲染2800万个三角形.我已经尝试了所有上述技术(据我所知),几乎没有性能变化.

虽然我在实施中收到大约40FPS,这绝不是问题,但我仍然很好奇这些优化'技巧'实际上在哪里使用?

我的CPU在渲染过程中空闲了大约20-50%,因此我认为我是GPU必须提高性能.

注意:我现在正在研究gDEBugger

Cross在Game Development上发布

dat*_*olf 25

第1点是显而易见的,因为节省了填充率.如果首先处理对象背面的基元,则将省略这些面.然而,现代GPU可以很好地容忍透支.我曾经(GeForce8800 GTX)在显着性能下降之前测量了高达20%的透支.但最好是保留这个储备,例如遮挡剔除,混合几何体的渲染等.

第2点是毫无意义的.从来没有在GPU上计算过矩阵 - 好吧,如果你不算SGI Onyx.矩阵总是只是在CPU上计算的某种渲染全局参数,然后被推入GPU上的全局寄存器,现在称为统一,因此加入它们只有很少的好处.在着色器中仅保存一个额外的向量矩阵乘法(归结为4个MAD指令),代价是算法灵活性较低.

第3点是关于缓存效率的.属于一起的数据应该适合缓存行.

第4点是关于防止状态变化破坏缓存.但这很大程度上取决于他们所说的GL呼叫.换制服很便宜.切换纹理很昂贵.原因是,一个制服位于寄存器中,而不是缓存的某些内存.切换着色器是很昂贵的,因为不同的着色器表现出不同的运行时行为,从而破坏了管道执行预备,改变了内存(以及因此)高速缓存访​​问模式等等.

但这些都是微观优化(其中一些具有巨大的影响).但是我建议寻找大的影响优化,比如实施早期Z传递; 在早期的Z中使用遮挡查询来快速区分整个几何批次.一个大的影响优化,主要包括总结很多Point-4类微优化,是按昂贵的GL状态对渲染批次进行排序.因此,使用常见着色器对所有内容进行分组,在这些组中按纹理排序等等.此状态分组仅影响可见渲染过程.在Z早期,您只测试Z缓冲区的结果,因此只有几何变换,片段着色器才会传递Z值.

  • @Daniel:您通常不在着色器中计算MVP矩阵.你要做的是首先执行计算modelview_position = MV*vertex_position,然后clip_position = P*modelview_position.这背后的原因是,对于某些算法,您需要在中间模型视图转换顶点位置,而不仅仅是整个投影过程的最终结果.顶点法线也只是通过MV的逆转置而不是完整的MVP ^ T ^ -1进行变换,这是另一个原因:如果你想实现漂亮的光照,你需要那些变换的法线. (3认同)