1
votes

I have a problem that has been torturing me for a month, and maybe more. There is a large background of about 9000x13000 pixels. And I am trying to bring this background to the screen. Since my video card only supports textures with a resolution of not more than 8192x8192 pixels, a black area is displayed instead of the texture. I compressed the image to 5000x7000 pixels. Now it is displayed, but the FPS has fallen to 50 (except for one image there is nothing). In addition, the game is also designed to work on mobile devices, and there the limitations of video cards can be 2048x2048 textures, and maybe less. I tried to break my big texture into 117 pieces (each not more than 1024x1024 pixels) and pull them one after another. Now the load of the game is about a minute and when the textures are output the FPS drops to 5! I tried to use filters

texture.setFilter(
    Texture.TextureFilter.MipMapNearestNearest,
    Texture.TextureFilter.Nearest
);

but the FPS did not go above 10. It also set the useMipMap flag to true when loading. At the moment I'm doing this:

Texture texture=new Texture(file, true);
texture.setFilter(
    Texture.TextureFilter.MipMapNearestNearest,
    Texture.TextureFilter.Nearest
);
public void render()
{
    batch.begin();
    batch.draw(texture,0,0,Gdx.graphics.getScreenWidth(),Gdx.graphics.getScreenHeight());
    batch.end();
}

Tell me, how can I optimize the output of a large texture? This texture is a map, so when approaching large screens it should be clearly detailed.

I will be grateful for any help

1
I guess not all of the 117 parts are visible all the time. How about only rendering those that are?BDL
Yes, i tried to render only those parts that are visible on the screen, and the FPS was about 30, but with the increase in the map, the FPS fell again to 5Ryder95
Unfortunately I do not think there are any optimizations that can be done. Unless you write the rendering code in a more performant language there isn't much to be done :/Micheal O'Dwyer
However, couldn't you just use a Tiled map or similar tiled map to display the huge texture. If any sections of the texture are the same then they can be stored and rendered as tiles which may mean performance gains.Micheal O'Dwyer
Unfortunately, the map does not have duplicate elements - it's just a detailed drawing created by the artistRyder95

1 Answers

0
votes

I didn't test it with libgdx, but I think it worth to try to have several variations of the texture/textures which are selected to be displayed depending on the current zoom level in your game in addition of having an original texture sliced into pieces. Think about loading pictures in Google Maps, when you zoom in.

The idea

Let's define the zoom level, as a number in the following way:

  • 1 is maximum zoom
  • 2 is zoomed out by 2
  • 3 is zoomed out by 4
  • 4 is zoomed out by 8
  • ...

Then here is how the textures are defined:

  1. Slice original texture into pieces of 2048x2048 (~ 7x5 = 35 pieces, texture with size 2048 is supported by the majority of the mobile devices). Use those for the zoom level 1. In this case you will have maximum 4 textures loaded at the same time.
  2. Scale down the original texture by 2 and slice into pieces again. This will give you about 9 textures. Use those for zoom level between 1 and 2.
  3. Scale down one more time => 3 textures. Use those for levels between 2 and 3.
  4. And one more time => for level 3 and greater. You can stop here.

Now when the user zoomed out, you use the texture #4. When the user zoomed in to level 3 or less, you still show the texture #4, while the set of zoomed textures is loading. Then you do a smooth transition using fadeIn/out for better visual impression.

More hints

  1. For faster loading of the textures, consider using compressed textures. The file size of compressed texture is usually comparable to PNG, but it can be loaded much faster into video memory and uses the same amount of RAM as the original file. (Because it does not need to be uncompressed into raw bitmap). Especially consider ASTC. ASTC is not supported by older devices, but I think your requirements are to high to make your game run on them.
  2. Load textures into memory only if user zoomed into the appropriate level. Unload textures after user zoomed out. This should be fast enough, because of the texture compression. I would keep the texture #4 always in memory for smoother UX. Probably it makes sense to keep intermediate levels because of the same reason (e.g. keep textures from set #3, while zoomed in into level 2).
  3. For better loading/unloading of the textures, think more about user behaviour (like what is typical usage of the zoom). Or probably you can use some kind of LRU Cache and unload textures "automatically".