OpenGL - 更新模型信息的最有效方法(例如模型矩阵)

时间:2017-11-27 21:49:05

标签: c++ opengl

因此,假设我已将OpenGL的常规缓冲区对象工作流抽象为Model类。我需要做的就是让3D模型出现在OpenGL上下文中,初始化Model对象,将其添加到容器中,并将容器中的所有Models绘制到渲染循环中。 假设我的场景中有1000个模型。我设置模型的全局坐标的方式现在变得非常重要。

我知道有几种方法可以更新模型信息,例如模型矩阵。一个是为每个模型共享一个着色器程序,并使用glUniformMatrix4fv在渲染循环中绘制每个模型之前为着色器设置模型矩阵。另一种方法是每个Model对象包含自己的着色器程序,并且在初始化Model对象时设置该着色器的模型矩阵。然后,在渲染循环中,glUseProgram在绘制之前用于每个模型着色器程序。

更新模型信息的最有效方法是什么,例如模型矩阵(我觉得我目前已知的方法效率极低)?

1 个答案:

答案 0 :(得分:2)

由于你的问题有点笼统,我也会保持答案的一般性。

通常,在OpenGL绘制调用之间更改状态是昂贵的,因此通过最小化状态更改可以实现最佳性能。但是,并非所有州的变化都是平等的。由于它们在供应商,驱动程序版本等之间的成本变化,所以状态变化比其他变更成本的详尽列表实际上是不可能的。很好地理解完整的OpenGL管道以及计算机硬件如何工作可以直观地了解哪些代码路径是更好。阅读专注于优化图形引擎性能的Nvidia和AMD演示文稿(来自GDC,Siggraph等)也非常有用。

对于您提出的具体问题,使用不同着色器(每个着色器包含自己的矩阵)比共享单个着色器并在每次绘制调用之前将矩阵设置为统一值更可能要慢得多。更改活动着色器需要驱动程序重新配置GPU管道,而不是简单地将16个浮点数写入GPU内存。还有其他一些技术可以让您将所有矩阵存储在一个缓冲区中,如果它们使用相同的着色器,则会与所有模型发出一次绘制调用。

一种方法是在一个SSBO或UBO中将所有矩阵放在一个数组中。然后每个网格都有一个索引,指示它应该使用哪个矩阵。索引可以来自顶点属性(如顶点位置的w分量)。