Christoph Bühler
Christoph Bühler

Reputation: 2923

How can I increase map rendering performance in HTML Canvas?

We are developing a web-based game. The map has a fixed size and is procedually generated.

enter image description here

At the moment, all these polygons are stored in one array and checked whether they should be drawn or not. This requires a lot of performance. Which is the best rendering / buffering solution for big maps? What I've tried:

Upvotes: 1

Views: 531

Answers (2)

Christoph Bühler
Christoph Bühler

Reputation: 2923

I have tried a lot of things and this solution turned out to be the best for us. Because our map has a fixed size, it is calculated server-side. One big image atlas with all the required tiles will be loaded at the beginning of the game. For each image on the atlas, a seperate canvas is created. The client loads the whole map data into one two-dimensional array. The values determine, which tile has to be loaded. Maybe it would be even better if the map was drawn on a seperate canvas, so that only the stripes have to be painted. But the performance is really good, so we won't change that.

Three conclusions:

  • Images are fast. GetImageData is not!
  • JavaScript has not yet great support for multi threading, so we don't calculate the map client-side in game-time.
  • Quadtrees are fast. Arrays are faster.

Upvotes: 0

GameAlchemist
GameAlchemist

Reputation: 19294

(posting comments as an answer for convenience)

One idea could be, when the user is translating the map, to re-use the part that will still be in view, and to draw only the stripe(s) that are no longer corrects.

I believe (do you confirm ?) that the most costly operation is the drawing, not to find which polygon to draw.
If so, you should use your QuadTree to find the polygons that are within the strips. Notice that, given Javascript's overhead, a simple 2D bucket that contains the polygons that are within a given (x,y) tile might be faster to use (if the cost of the quadtree is too high).

Now i have a doubt about the precise way you should do that, i'm afraid you'll have to experiment / benchmark, and maybe choose a prefered browser.
Problems :
• Copying a canvas on itself can be very slow depending on devices/Browsers. (might require to do 2 copy, in fact)
• Using an offscreen canvas can be very slow depending on devices/Browsers. (might not use hardware acceleration when off-screen).

If you are drawing things on top of the map, you can either use a secondary canvas on top of the map canvas, or you'll be forced to use an off-screen canvas that you'll copy on each frame.

Upvotes: 1

Related Questions