Scala OpenGL如何渲染具有多个对象的基于体素的世界场景

Scala OpenGL如何渲染具有多个对象的基于体素的世界场景,scala,opengl,game-engine,Scala,Opengl,Game Engine,我正在使用OpenGL绑定的JVM语言(scala是我的例子)开发一个体素游戏引擎—LWJGL 3用于OpenGL 4.5版。目前我一直使用块渲染(32*32*32块)。为了渲染任何对象,我首先给它一个唯一的ID,将类似的对象(如简单块)视为具有不同转换的对象,在初始化阶段创建一个VAO数据对象,在所有准备工作完成后,我渲染一个循环通过每个块的整个块,将其数据传递给着色器,然后调用具有适当偏移量(取自ID)的抽屉元素。这样,fps从3000(3条轴线和一个巨大的网格对象分别渲染)下降到1-2。那

我正在使用OpenGL绑定的JVM语言(scala是我的例子)开发一个体素游戏引擎—LWJGL 3用于OpenGL 4.5版。目前我一直使用块渲染(32*32*32块)。为了渲染任何对象,我首先给它一个唯一的ID,将类似的对象(如简单块)视为具有不同转换的对象,在初始化阶段创建一个VAO数据对象,在所有准备工作完成后,我渲染一个循环通过每个块的整个块,将其数据传递给着色器,然后调用具有适当偏移量(取自ID)的抽屉元素。这样,fps从3000(3条轴线和一个巨大的网格对象分别渲染)下降到1-2。那么,我应该如何正确地呈现块呢

我用教程作为参考

Fps投放代码:

def render(shader:Shader): Unit ={
for(x <- 0 until SIZE) {
  for (y <- 0 until SIZE) {
    for (z <- 0 until SIZE) {
      val obj = blocks(x)(y)(z)
      if(obj != null){
        val M = obj.getTransformationMatrix() * Matrix4F.matrixTRANSLATION(obj.getPosition())
        shader.setUniformMat4f("M", M)
        shader.setUniformMat4f("MI", M.inverse())
        shader.setUniformBool("lightInteraction", obj.lightInteraction)
        shader.setUniform1f("smoothness", obj.smoothness)
        shader.setUniform3f("matD", obj.matDiffuse)
        shader.setUniform3f("matS", obj.matSpecular)
        GL13.glActiveTexture(GL13.GL_TEXTURE0); // Texture unit 0
        glBindTexture(GL_TEXTURE_2D, obj.getTextureID())

        Shader.full.setUniform1i("tex", 0)
        RenderRegistry.getRenderManager().render(obj.getID, obj.getRenderType())
      }
    }
  }
}
}
def渲染(着色器:着色器):单位={

对于(x,您当前的代码正试图执行32768(32*32*32)矩阵乘法、求逆、均匀上载和每帧纹理状态更改。通常,这些操作成本很高,而且对于块中的每个对象可能并不都需要。幸运的是,优化的方法很少

按纹理/材质分组 很可能有些对象共享相同的着色器参数和纹理。绑定这些值,然后绘制所有共享这些值的对象,应该可以恢复一些性能

实例渲染 由于有一个关于这个主题的优秀教程,所以我不会对此进行太多讨论。假设所有体素都使用相同的几何体并且大部分是静态的,您可以在缓冲区中上载变换矩阵并上载顶点对象一次。这一好处部分取决于您的图形驱动程序,但对于大型体素场景,它可能会这是值得的

将矩阵运算移动到GPU
这是次要的,但是如果您不想麻烦实例化,您至少可以在矩阵操作上保存一些周期。不要上载
M.inverse()
,而是调用
inverse(M)在GPU上,也可以考虑将体素位置上传并统一变换为GPU上的“代码→变换→位置/代码>”。在GPU上,如果你能计算一次(在CPU上)。如果n是一个大数字,GPU不会更快,但事实上相反。GPU不是神奇的,你知道。请参阅: