我正在使用OpenGL绑定JVM语言的体素游戏引擎(scala是我的情况) - 用于OpenGL 4.5版的LWJGL 3。目前,我仍然坚持使用块渲染(32 * 32 * 32块)。为了渲染任何对象,我首先给它一个唯一的ID,将类似的对象(如简单的块)处理为具有不同转换的对象,在初始化阶段创建一个VAO数据事物,并且在完成所有准备工作之后,我渲染整个块,循环遍历每个块,将其数据传递给着色器,然后调用具有适当偏移量的drawElements,取自ID。这样,fps从3000(从3轴线和一个巨大的网格对象单独渲染)下降到1-2。那么我应该如何正确渲染一个块呢?
我使用basic-block-rendering教程作为参考。
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())
}
}
}
}
}
答案 0 :(得分:0)
您当前的代码尝试执行32768(32 * 32 * 32)矩阵乘法,反转,统一上传和每帧纹理状态更改。通常,这些是昂贵的操作,并且它们可能对于块中的每个单个对象都不是必需的。幸运的是,很少有优化方法。
有些对象可能共享相同的着色器参数和纹理。绑定这些值,然后绘制共享它们的所有对象应该恢复一些性能。
我不太了解这一点,因为这是一个很好的教程here。假设您的所有体素都使用相同的几何体并且大部分是静态的,您可以在缓冲区中上传转换矩阵并上传顶点对象一次。这样做的好处部分取决于你的图形驱动程序,但对于大型体素场景,它可能是值得的。
这很小,但如果你不想打扰实例,你至少可以在矩阵操作上节省一些周期。请勿上传M.inverse()
,而是在GPU上调用inverse(M)
。还可以考虑上传体素位置并单独转换为制服并在GPU上执行transform*position
。