# Big maps with deep zoom and pan

I have a world map of 14048x7134, the game starts with the zoom completely out and during the operation it zoom in and zoom out and pan in all directions, it can get really near the surface, at almost a 1:1 ratio between the screen and the map information. It is going to be draw in a 1024x768 screen.

Scale a 14048x7134 to fit 1024x768 in each frame it's way far from efficient, so I am wondering... What strategies there are to solve this problem? Is there any tool or library to help in this process?

If you have access to shaders, you can invert the drawing logic. Normally you loop through tiles and draw each one. When you're zoomed out there are a lot of tiles to draw. Zooming out is slower. Inverting the logic, you can loop through pixels and figure out which tile that pixel is on, and that tells you which sprite to draw, and then you look up a color in the sprite. This is weird but it means that no matter what zoom level, you have the same number of draw calls (just one quad), and the same amount of work to do, at least for the tiles. The objects on top of the map don't work with this trick so you'll still have to draw them separately.

To make it work you put the game map into a texture. The texture color tells you which tile to use. You also have the tile sprites in another texture. For example if you have 32x32 pixel tiles, and 16x16 of them, you can put that into a 512x512 texture. If the game map is 200x200 you can put that into a 200x200 texture, where each color is {red = 0.0 for column 0 to red = 1.0 for column 15, green = 0.0 for row 0 to 1.0 to row 15}.

If the tile to draw is in column 3, row 9, then you'd store {red = 3/15, green=9/15} as the color. The shader then looks up the tile coordinates first. It would see that it needs to look in the spritesheet at column 3 (which starts at pixel x=3*32) and row 9 (which starts at pixel y=9*32). It then calculates which pixel of the sprite it needs to draw, and looks that color up in the spritesheet.

I had tried this out a long time ago with this flash demo, and then I tried to find other people who had the same idea and found this javascript demo and a blog post about the technique. Some of the comments on that blog post suggest that it may not actually be that efficient of a shader, so if you're going to try this it's worth measuring the performance.

You can create something like level of details for this. There are three ways you can handle this:

I. Create tiles that will cover the same amount of screen but have smaller resolution. You stay with same number of draw calls but with less data per draw.

II. Create tiles that are bigger so you get less draw calls.

III. Merge this two methods and create bigger tiles but also with less data per tile of normal size.

Third option is the best in my opinion. When you zoom out there will be lack of details so there is no reason to render tiles with all data.

Of course this will take more memory and you will need to calculate which tile render depend on distance from camera.

Also if this is one big image and you can write shader for rendering you can just change vertices uv's in shader. With this you can render just one quad (2 triangles) and I think this is the best solution ;)