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