3
\$\begingroup\$

I'm trying to figure out the best way of rendering my layered tiled maps with WebGL, and have come across this tutorial several times: https://blog.tojicode.com/2012/07/sprite-tile-maps-on-gpu.html

Someone even created a library for it here: https://github.com/englercj/gl-tiled

The gist of this "GPU abuse" seems to be generate a texture where each pixel as a lookup table into the tileset spritesheet. That is, the red component refers to the x coordinate and the green component refers to the y coordinate. Additionally, in the library, the blue component refers to the corresponding tileset to use.

This seems to accomplish exactly what I am attempting to do, but I am confused on two parts.

For one, the author describes this is a neat little trick and "GPU abuse". I feel as if the implication there is, "this is a fun little exercise, but don't actually use this for your game or any serious code."

Is this the case, or is this actually a potentially serious technique that I could use to power my map rendering?

Secondly, I'm somewhat confused why this is even necessary. I am still learning WebGL, so I might mess up a few terms here, but couldn't this same exact thing be accomplished in a more straight-forward manner? Why go through all these steps of creating a custom generated texture of your map, when you can just create a (static?) Vertex Buffer Object, load it with all your tiles, and then just render them?

I'm not really understanding what exactly this technique buys as that can't be accomplished in the same way by just creating a large buffer that just contains all our tile data, and then just rendering it like that. Isn't that conceptually simpler, arguably easier to implement, more straight-forward, and doesn't have weird restrictions like maximum tile count or width?

Basically, I'm having trouble understanding what advantages this has over traditional rendering where you just load up a buffer with tiles. If there are some advantages, should this technique be seriously used in a game?

\$\endgroup\$
5
  • 1
    \$\begingroup\$ It's not abuse. You are free to use the GPU however you want. \$\endgroup\$
    – user253751
    Mar 23, 2021 at 15:47
  • \$\begingroup\$ Also VBOs can't contain tiles, only vertex data. What would that vertex data look like? \$\endgroup\$
    – user253751
    Mar 23, 2021 at 15:47
  • 1
    \$\begingroup\$ You're correct about the gist, but left out one important element: it's only ever pushing 4 vertices through the GPU, instead of 4 for every single tile (as one might do in the "naïve" implementation). A single quad will generally render a lot faster than hundreds. The spritesheet itself is a similar trick -- by combining all the tile textures into one single texture, we can minimize the amount of work the GPU has to do, resulting in quicker renders and more frames per second. \$\endgroup\$
    – A C
    Mar 24, 2021 at 3:25
  • \$\begingroup\$ @AC Isn't the GPU parallel? Why would rendering one quad be faster than 100? Wouldn't all 100 be rendered at the same time anyway? \$\endgroup\$ Mar 24, 2021 at 20:18
  • \$\begingroup\$ One benefit of that technique is that it uses less memory. It only stores one vec3 per tile. With vertex data, you would need to store that data for each vertex (there are 4 vertices in each tile). I can't think of any problems with the technique (just the limitations that are mentioned in the article, such as the texture size limitation, but you could work around it anyways). \$\endgroup\$
    – tuket
    Apr 19, 2021 at 20:44

2 Answers 2

1
\$\begingroup\$

This technique has the advantage that you can render the whole tile layer as one single quad. That means that there are just 4 vertices that need to go through the vertex shader. The rest happens in the pixel shader. You do a lookup in the tiny texture to see in which part of which tileset texture you need to do the lookup that provides the actual RGBA values for the tile. This could (potentially) be a pretty fast way to render a tilemap. Much faster than rendering each tile as a separate quad, or even as a separate draw-call.

However, I am a bit skeptical if you really need to resort to such tricks with today's hardware. This is 2d, after all. I wrote tilemap-based engines using the 2d API of HTML5 canvas (so even slower because you do quite a lot on the CPU layer) and didn't have any performance issues - and that was 10 years ago. So if VBOs work for you, then I doubt that there is much reason for you to change that.

\$\endgroup\$
-2
\$\begingroup\$

WebGL is not really needed for sprite tilemaps at this point in time. The overhead for WebGL would slow a sprite based web game down.

One sprite sheet that has all image data, animations, and everything loaded as an Image, drawn from directly to canvas, that's all that's needed.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .