Nov 2012

This is an experiment with shader rendering of maps at multiple zoom levels. The map is 2^32 (4,294,967,296) pixels. Instructions: click, then use left/right to change magnification, or up/down to change other settings. Notes below.

  1. Supports animated tiles. Zoom in to magnify=50 to see a simple example.
  2. Supports different styles of drawing at different zoom levels. Zoom out to magnify=19 to see solid blocks.

It's 4 gigapixels, but it's made with tiles. Typically when you zoom out you have more tiles to draw, so things slow down. Here, the map is 512x512 tiles, so fully zoomed out, you'd need 262,144 quads. I inverted the logic, putting the tile drawing into the shader so that no matter how many tiles you have to draw, it's the same speed. It's just one quad, and all the lookups are in the shader.

The main idea is to have one bitmap that represents the tile map (one pixel per grid tile) and a second bitmap that has tile graphics (optionally animated). The shader looks up the tile id from the tile map, then looks up the graphics from the second bitmap. At different zoom levels, the tile graphics can be different. That's what allows the zoomed-in version to be a hollow box with a circle in it, and the zoomed-out version to be a solid box. As the game map changes, you need to update the (small) first bitmap, but the (large) second bitmap stays the same. There are some unresolved quirks when zooming way out; in a game you would use a different sprite at those zoom levels.

I ran into a bug with my code when I tried implementing this with mipmaps. I ended up manually switching textures and it worked much better.

I'm happy with the experiment but the shader may be too expensive. Also see this experiment from mikolalysenko and this blog post I found later.