因此,可以说我已经将OpenGL的常规缓冲区对象工作流抽象为Model类。要使3D模型显示在OpenGL上下文中,我要做的只是初始化Model对象,将其添加到容器中,然后将容器中的所有Model绘制到渲染循环中。
可以说我的场景中有1000个模型。现在,我设置模型全局坐标的方式变得非常重要。
我知道有几种方法可以更新模型信息,例如模型矩阵。一个方法是为每个模型共享一个着色器程序,并在渲染循环中绘制每个模型之前使用glUniformMatrix4fv为着色器设置模型矩阵。另一种方法是让每个Model对象包含其自己的着色器程序,并在初始化Model对象时设置该着色器的模型矩阵。然后,在渲染循环中,在绘制之前,将glUseProgram用于每个Models着色器程序。
更新模型信息(例如模型矩阵)的最有效方法是什么(我觉得我目前已知的方法效率极低)?
最佳答案
由于您的问题有些笼统,因此我也将答案保留为笼统。
通常,在OpenGL绘制调用之间更改状态的成本很高,因此,通过最小化状态更改可获得最佳性能。但是,并非所有状态更改都相等。实际上,不可能详尽列出状态更改比其他更改成本更高的原因,因为它们的成本在供应商,驱动程序版本等之间会发生变化。对完整的OpenGL管道以及计算机硬件的工作方式有很好的了解可以直观地了解哪些代码路径是更好。阅读专注于优化图形引擎性能的Nvidia和AMD演示文稿(来自GDC,Siggraph等)也非常有帮助。
对于您提出的特定问题,使用不同的着色器(每个包含自己的矩阵)比共享单个着色器并在每次绘制调用之前将矩阵设置为统一值的速度要慢得多。更改 Activity 着色器要求驱动程序重新配置GPU管道需要进行更多工作,而不仅仅是将16个浮点数写入GPU内存。还有其他技术可以让您将所有矩阵存储在单个缓冲区中,并且如果所有模型使用相同的着色器,则可以对所有模型发出单个绘制调用。
一种方法是将所有矩阵排列在单个SSBO或UBO中。然后,每个网格都有一个索引,指示应该使用哪个矩阵。索引可以来自顶点属性(例如顶点位置的w分量)。
关于c++ - OpenGL-更新模型信息的最有效方法(例如模型矩阵),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47520391/