Search code examples
javaopengllwjglmipmaps

Why does mipmapping give me barely any performance increases?


I am rendering grass with 8 vertices per piece of grass (per object). This brought my game down from 50+ FPS to exactly 31FPS.

Trying to find a solution to this, I stumbled across a Mipmapping tutorial, a way to make the texture less detailed. "Great", I thought! Since the grass is just two flat surfaces with a texture on, it looked like it would solve the issue!

The grass model looks like this (Obviously I then just apply a texture to it and make certain parts transparent using shaders):

enter image description here

However, when I enabled mipmapping, I got 32 FPS - Only 1 more FPS than without mipmapping! I also get some sort of blue tinge on the grass? enter image description here

Without mipmapping, the grass looks like this: enter image description here

Why is my Mipmapping not giving me any sort of performance enhancements? Considering my grass is mostly just texture, then why would degrading the texture not increase performance?

And also, why is there a blue tinge being created on the grass? Is it something to do with how mipmapping is lowering the texture resolution?

I currently use this code to generate:

texture = TextureLoader.getTexture("PNG",
                new FileInputStream("res/" + fileName + ".png"));
        GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR_MIPMAP_LINEAR);
        GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL14.GL_TEXTURE_LOD_BIAS, 0);

And I use this code to actually render the grass:

public void render(){
    Main.TerrainDemo.shader.start();
    glPushMatrix();
    glTranslatef(location.x, location.y, location.z);
    TexturedModel texturedModel = TerrainDemo.texModel;
    RawModel model = texturedModel.getRawModel();
    GL30.glBindVertexArray(model.getVaoID());
    GL20.glEnableVertexAttribArray(0);
    GL20.glEnableVertexAttribArray(1);
    GL13.glActiveTexture(GL13.GL_TEXTURE0);
    GL11.glBindTexture(GL11.GL_TEXTURE_2D, texturedModel.getTexture().getID());
    glScalef(10f, 10f, 10f);
    glDrawElements(GL_TRIANGLES, model.getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
    GL20.glDisableVertexAttribArray(0);
    GL20.glDisableVertexAttribArray(1);
    GL30.glBindVertexArray(0);
    glPopMatrix();
    Main.TerrainDemo.shader.stop();
}

Solution

  • The mip-mapping modifies the texture, but the grass doesn't really do much work in the texture anyway as it is a small object.

    Most of the work to render the grass comes in processing all of the vertices, and most especially if the grass are lots of small objects then in processing these objects.

    You should combine the grass together into one mesh and then let that be rendered. Graphics cards are great at handling objects with huge numbers of vertices, not so great at huge numbers of objects.

    If you were using jMonkeyEngine I could recommend some classes that provides to do the batching for you (most obviously BatchNode although there are some other options too). It might still be worth looking at how jMonkeyEngine does it for ideas.