Jump to content

Large map from performance point of view


Tom Atom
 Share

Recommended Posts

Hi, I would like to ask for your opinions in this matter: I need to show big map. This map is not made from tiles. It is big picture - bigger than screen, so camera will scroll over it. I am looking for best way from performance point of view.

 

Here are my options so far:

1) single big image, camera is moving over it. Like this Phaser example: http://phaser.io/examples/v2/camera/basic-follow But I think that non visible parts are also processed by GPU? So, is it wasting of processing time?

2) load image and change it into tilemap. Should be easy - I will mark image as spritesheet and create tilemap with tiles like 0, 1, 2, 3, 4. Only tiles in camera view are drawn with tilemap, so it should be more performant. But, I can have only one image 2048x2048 with this (mobile safe size of texture). What if I wanted map like 4096x4096. Again, map is not made from tiles - it is big picture. I do not see any possibility to have multiple tilemaps side by side

 

Link to comment
Share on other sites

Hi, I would like to ask for your opinions in this matter: I need to show big map. This map is not made from tiles. It is big picture - bigger than screen, so camera will scroll over it. I am looking for best way from performance point of view.

 

Here are my options so far:

1) single big image, camera is moving over it. Like this Phaser example: http://phaser.io/examples/v2/camera/basic-follow But I think that non visible parts are also processed by GPU? So, is it wasting of processing time?

2) load image and change it into tilemap. Should be easy - I will mark image as spritesheet and create tilemap with tiles like 0, 1, 2, 3, 4. Only tiles in camera view are drawn with tilemap, so it should be more performant. But, I can have only one image 2048x2048 with this (mobile safe size of texture). What if I wanted map like 4096x4096. Again, map is not made from tiles - it is big picture. I do not see any possibility to have multiple tilemaps side by side

Divide your map into several pieces (ex: 2 pieces if 4096x4096) and load them piece by piece. You can maintain the resolution you want as long as the max resolution per piece is below the threshold allowed by Phaser.

Link to comment
Share on other sites

Divide your map into several pieces (ex: 2 pieces if 4096x4096) and load them piece by piece.

 

thanks, but this brings me back to core of the question - If I divide it then I will have more than one big images to display. I think, that even the images not visible at time will have to be processed by GPU (at least to some point before it calculates, that fragment is out of camera)

 Option 2 was about cutting it into tiles, but in this case I am limited to only one image (up to 2048x2048) as there is not possibility to "tile" multiple tilemaps side to side or use multiple spritesheets for one tilemap.

Link to comment
Share on other sites

The maximum texture size is GPU specific. Mobile GPUs for example have a lower limit than desktop, and desktop comes in all kinds of variations depending on spec. I wouldn't go any higher than 2048x2048 per tile, and I'd be very careful about how many tiles you had in total too.

 

I'd also question if you really need something of that fidelity or not. Could you get away with lower res upscaled? Or a more cleverly composited image? It depends entirely on the graphic itself though.

Link to comment
Share on other sites

thanks, but this brings me back to core of the question - If I divide it then I will have more than one big images to display. I think, that even the images not visible at time will have to be processed by GPU (at least to some point before it calculates, that fragment is out of camera)

 Option 2 was about cutting it into tiles, but in this case I am limited to only one image (up to 2048x2048) as there is not possibility to "tile" multiple tilemaps side to side or use multiple spritesheets for one tilemap.

I'm not sure how the GPU process the loading of images but you can always divide your large image into several pieces and not necessarily in 2 if you are still taking the 4096x4096 case. Loading a 1024x1024 image instead should be faster to process no?

Link to comment
Share on other sites

I added image below to explain better my problem. Let's say my map is 2048x2048. This can be split into four 1024x1024. Red rectangle is game screen. In this case all four images (each one still quite a big) have to be processed - at least up to some point before GPU finds, that for example pixel 0,0 of upper left corner is out of screen and throws it away.

 

post-12887-0-39428800-1446496040.png

 

 Tilemap solves this for you - you can give it big texture and say: tile size is 128x128 for example and tilemap is NOT rendering tiles, that are not at least partially visible. But, your underlaying texture for tilemap can be up to 2048x2048 (safe for mobile GPU). So, tilemaps exactly do this image cutting job for you!

 

post-12887-0-42375200-1446496637.png

 

But here comes problem: what if map was 4096x4096? I can divide it into four safe 2048x2048 images, but I am back in first case - big parts of images that are not visible will have to be processed. And I cannot use solution with tilemaps, as I cannot have multiple tilemaps side by side (each having one of four 2048x2048 images as spritesheet). Or can I, somehow?

Link to comment
Share on other sites

The maximum texture size is GPU specific. Mobile GPUs for example have a lower limit than desktop, and desktop comes in all kinds of variations depending on spec. I wouldn't go any higher than 2048x2048 per tile, and I'd be very careful about how many tiles you had in total too.

 

I'd also question if you really need something of that fidelity or not. Could you get away with lower res upscaled? Or a more cleverly composited image? It depends entirely on the graphic itself though.

 

Very often match-3 games have really large maps. In Candy Crush you can scroll for ages, but they are faking it with gradient only and some items here and there. But there are games (even HTML5 ones) like Jewel Academy ( http://www.agame.com/game/jewel-academy) that has also big map made from lot of images.

 

Upscale is good idea - scaling a bit (let's say 20%) can bring big area in 2D (1.2 x 1.2 = 1.44 .... +44%). My idea is to make some reusable solution for such a big maps (not only vertical like Jewel Academy, but any rectangle) that takes care of safe texture size (2048x2048) for single part, but does not care of total texture memory (this is up to developer).

Link to comment
Share on other sites

The biggest cost in terms of GPU is memory bandwidth. I.e. the amount of textures you can get in GPU memory before it runs out and has to start swapping from system RAM. The amount here differs dramatically based on hardware. But the important fact is that once your textures are uploaded to the GPU, that's it - you can pretty much blast them around as much as you like without incurring too much overhead. This is especially true in 2D where a single image is just two quads and a texture anyway. As long as the textures are loaded then the GPU will hardly break a sweat rendering them, even if half of it isn't even in the viewport.

 

Let's say you're working with an 8192x8192 image you want to display. Break that up in to 4 separate 2048x2048 images. Assuming no mipmaps or texture compression that's 16MB GPU memory per texture, so 128MB in total. Lots of devices can't handle that amount, but maybe you don't have to worry? Maybe this is desktop only? Breaking it up into smaller tiles won't help as you still need the same amount of memory in total. Tiles would only help if the nature of the image means that some tiles are repeated.

 

Depending on the game depends on how you solve this, but I'd say your issue isn't worrying about viewport culling, it's worrying about how to get the textures on the GPU in the first place without grinding to a halt (because pushing up 128MB of textures will be noticeable no matter how you do it!).

Link to comment
Share on other sites

@rich: thanks - viewport culling was my biggest worry (to completely avoid processing of pixels out of view). But if culling is "cheap" then it should be OK. I do not plan to kill GPU with so many textures - I just want to have comfortable solution, where you can just say: ok, here are these images and display it as one big. If culling is not block, then solution is easy: just to pass coordinate of top left corner of each image.

Link to comment
Share on other sites

It all depends on the game of course. If say you have a really tall map and you're only scrolling from bottom to top, then you can start with just the bottom set of textures on, and as you move up you clear those out and load the next set to appear above them. Ultimately though I would always try and go for the 'clever' route as you've mentioned, i.e. gradient backgrounds, tiled images, repeated cells, etc.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...