在libgdx的一侧构建一个带纹理的框 - 性能

Art*_*hur 5 android opengl-es libgdx

在类似拼字游戏的3D游戏中,我遇到的性能问题只有8 FPS.把它缩小到字母瓷砖.其中有100个,减少数量可以迅速提高性能.我排除了纹理绑定,因为即使所有图块具有与屏幕截图相同的纹理,速度也不会提高.

截图

这就是我创建每个盒子的方式:

public static void createModel() {
  matWhite = new Material(ColorAttribute.createDiffuse(Color.WHITE));
  ModelBuilder modelBuilder = new ModelBuilder();
  modelBuilder.begin();
  MeshPartBuilder tileBuilder;
  tileBuilder = modelBuilder.part("top", GL10.GL_TRIANGLES, Usage.Position | Usage.Normal | Usage.TextureCoordinates, matWhite);
  tileBuilder.rect(-0.45f, 0.1f, 0.45f,   0.45f, 0.1f, 0.45f,    0.45f, 0.1f, -0.45f,  -0.45f, 0.1f, -0.45f,  0f, 1f, 0f);
  tileBuilder = modelBuilder.part("bottom", GL10.GL_TRIANGLES, Usage.Position | Usage.Normal, matWhite);
  tileBuilder.rect(-0.45f, 0f, -0.45f,    0.45f, 0f, -0.45f,     0.45f, 0f, 0.45f,     -0.45f, 0f,  0.45f,    0f, -1f, 0f);
  tileBuilder = modelBuilder.part("front", GL10.GL_TRIANGLES, Usage.Position | Usage.Normal, matWhite);
  tileBuilder.rect(-0.45f, 0.1f, 0.45f,  -0.45f, 0f, 0.45f,      0.45f, 0f, 0.45f,      0.45f, 0.1f,  0.45f,    0f, 0f, 1f);
  tileBuilder = modelBuilder.part("left", GL10.GL_TRIANGLES, Usage.Position | Usage.Normal, matWhite);
  tileBuilder.rect(-0.45f, 0.1f, 0.45f,  -0.45f, 0.1f, -0.45f,  -0.45f, 0f, -0.45f,    -0.45f, 0f,  0.45f,    -1f, 0f, 0f);
  tileBuilder = modelBuilder.part("right", GL10.GL_TRIANGLES, Usage.Position | Usage.Normal, matWhite);
  tileBuilder.rect( 0.45f, 0.1f, 0.45f,   0.45f, 0f, 0.45f,      0.45f, 0f, -0.45f,     0.45f, 0.1f,  -0.45f,    0f, 0f, 1f);
  tileBuilder = modelBuilder.part("back", GL10.GL_TRIANGLES, Usage.Position | Usage.Normal, matWhite);
  tileBuilder.rect(-0.45f, 0.1f, -0.45f,  0.45f, 0.1f, -0.45f,   0.45f, 0f, -0.45f,    -0.45f, 0f,  -0.45f,    0f, 0f, 1f);
  modelTile = modelBuilder.end();
}

public void createModelInstance(com.badlogic.gdx.assets.AssetManager assetManager) {
  Texture texTile = assetManager.get("textures/" + textureFile + ".jpg", Texture.class);
  Material mat = new Material(TextureAttribute.createDiffuse(texTile));
  modelInstance = new ModelInstance(modelTile); 
  modelInstance.nodes.get(0).parts.get(0).material.set(mat);
}
Run Code Online (Sandbox Code Playgroud)

在进行实验时,我发现速度上升到25 FPS(即使使用了所有100个纹理)如果我用创建一个简单的框来替换网格部件构建代码(它显示了所有边的纹理,所以它对这个游戏不是很有用) ).他们的createBox方法也调用了rect()6次,但到目前为止我没有看到差异.

modelTile = modelBuilder.createBox(0.9f, 0.1f, 0.9f, matWhite, Usage.Position | Usage.Normal | Usage.TextureCoordinates);
Run Code Online (Sandbox Code Playgroud)

我在第一段代码中做错了什么?仅在一侧创建具有纹理的框的正确方法是什么?

Xop*_*ppa 5

每次调用modelBuilder.part它都意味着绘制调用.由于它们非常昂贵,您真的希望将绘制调用的数量保持在最低限度.此外,由于您具有不同的顶点属性,因此必须在第一个和其他部分之间切换网格和着色器.您还需要将网格和着色器开关的数量保持在最低限度.

因此,要开始优化,您可能希望将这些部分与相同的属性组合在一起:

tileBuilder = modelBuilder.part("top", GL10.GL_TRIANGLES, Usage.Position | Usage.Normal | Usage.TextureCoordinates, matWhite);
tileBuilder.rect(-0.45f, 0.1f, 0.45f,   0.45f, 0.1f, 0.45f,    0.45f, 0.1f, -0.45f,  -0.45f, 0.1f, -0.45f,  0f, 1f, 0f);
tileBuilder = modelBuilder.part("others", GL10.GL_TRIANGLES, Usage.Position | Usage.Normal, matWhite);
tileBuilder.rect(-0.45f, 0f, -0.45f,    0.45f, 0f, -0.45f,     0.45f, 0f, 0.45f,     -0.45f, 0f,  0.45f,    0f, -1f, 0f);
tileBuilder.rect(-0.45f, 0.1f, 0.45f,  -0.45f, 0f, 0.45f,      0.45f, 0f, 0.45f,      0.45f, 0.1f,  0.45f,    0f, 0f, 1f);
tileBuilder.rect(-0.45f, 0.1f, 0.45f,  -0.45f, 0.1f, -0.45f,  -0.45f, 0f, -0.45f,    -0.45f, 0f,  0.45f,    -1f, 0f, 0f);
tileBuilder.rect( 0.45f, 0.1f, 0.45f,   0.45f, 0f, 0.45f,      0.45f, 0f, -0.45f,     0.45f, 0.1f,  -0.45f,    0f, 0f, 1f);
tileBuilder.rect(-0.45f, 0.1f, -0.45f,  0.45f, 0.1f, -0.45f,   0.45f, 0f, -0.45f,    -0.45f, 0f,  -0.45f,    0f, 0f, 1f);
Run Code Online (Sandbox Code Playgroud)

并且为了进一步优化(消除所有网格切换),您可以使用相同的顶点属性.当然,这将在没有纹理的情况下向边添加纹理属性.但只要材料没有纹理,它们就会被忽略.

tileBuilder = modelBuilder.part("top", GL10.GL_TRIANGLES, Usage.Position | Usage.Normal | Usage.TextureCoordinates, matTop);
tileBuilder.rect(-0.45f, 0.1f, 0.45f,   0.45f, 0.1f, 0.45f,    0.45f, 0.1f, -0.45f,  -0.45f, 0.1f, -0.45f,  0f, 1f, 0f);
tileBuilder = modelBuilder.part("others", GL10.GL_TRIANGLES, Usage.Position | Usage.Normal | Usage.TextureCoordinates, matOthers);
tileBuilder.rect(-0.45f, 0f, -0.45f,    0.45f, 0f, -0.45f,     0.45f, 0f, 0.45f,     -0.45f, 0f,  0.45f,    0f, -1f, 0f);
...
Run Code Online (Sandbox Code Playgroud)

要进一步优化(消除所有着色器开关并减少绘制调用次数),您可以向纹理添加单个像素,这将由边使用并设置UV范围:

tileBuilder = modelBuilder.part("top", GL10.GL_TRIANGLES, Usage.Position | Usage.Normal | Usage.TextureCoordinates, matWhite);
tileBuilder.setUVRange(0,0,1,1);
tileBuilder.rect(-0.45f, 0.1f, 0.45f,   0.45f, 0.1f, 0.45f,    0.45f, 0.1f, -0.45f,  -0.45f, 0.1f, -0.45f,  0f, 1f, 0f);
tileBuilder.setUVRange(0,0,0,0); // Assumes the top left pixel is the correct color for the other sides
tileBuilder.rect(-0.45f, 0f, -0.45f,    0.45f, 0f, -0.45f,     0.45f, 0f, 0.45f,     -0.45f, 0f,  0.45f,    0f, -1f, 0f);
...
Run Code Online (Sandbox Code Playgroud)

现在,如果您仍然遇到性能问题,可以考虑将多个切片组合到一个模型中(部分:绘制调用).但是,对于上述变化,这可能不会立即发生.

更多信息:http://blog.xoppa.com/behind-the-3d-scenes-part1/