You can ignore power-of-two image sizes now

4
Official Construct Team Post
Ashley's avatar
Ashley
  • 17 Nov, 2016
  • 612 words
  • ~2-4 mins
  • 5,994 visits
  • 1 favourites

WebGL brings native-grade rendering to the web which Construct 2 games have long taken advantage of, but it always had two minor annoyances. The original WebGL (which I'll call WebGL 1) is based on OpenGL ES 2, and inherits some power-of-two (POT) restrictions: tiled images have to be a POT size (e.g. 32x32, 64x64, 128x128 etc), and it can only generate a mipmap (used for better quality downscaling) for POT size images. To work around the tiling issue, C2 internally stretches any non-power-of-two (NPOT) tiled images to a POT size before creating the texture, which is lossy. This combined with the mipmap restriction meant that there have occasionally been bug reports in the past about slightly degraded quality with certain images.

Fortunately WebGL 2 is coming, which is based on OpenGL ES 3 and lifts both those restrictions. C2 r240 and newer can use WebGL 2 if it's available. This means it can tile any size images without any quality loss, and always create mipmaps for any size images, so the downscaling quality is always the same (and best) quality. It's nice that we can finally solve these long-standing issues with WebGL 2!

Ignore power-of-two sizes

Once WebGL 2 is widespread, there is no longer any reason to consider whether an image is a POT size or not. You can pretty much just completely forget about the whole issue and use any-sized images with no consequences. Even on the slow-moving Android, over half of all devices already support OpenGL ES 3 (and therefore can support WebGL 2), and all other platforms will likely have far better support already. In the near future we can expect WebGL 2 to be pretty much as ubiquitous as WebGL 1 is today. Even on old browsers or devices which fall back to WebGL 1, the consequences are minor - just slightly degraded image quality in a small number of cases.

Spritesheeting

In fact, power-of-two sizes are the worst case size for a Sprite image. The spritesheet builder still uses POT size sheets for performance and compatibility, often at large sizes like 1024x1024 with lots of smaller images on them. However to avoid color bleeding issues it always adds at least a 1px border around each image, making it 2px longer on both dimensions. While POT sizes divide exactly in to a larger POT size, adding 2px to the size actually makes it divide the least efficiently! For example a 512x512 area can fit four times in to a 1024x1024 sheet, but when it's bumped up to 514x514 for the border, it can only fit once on a 1024x1024 sheet!

This means using a power-of-two size for images can actually make your game less efficient. The ideal packing size is actually a power-of-two minus 2px, e.g. 30px, 62px, 126px etc, since once you add the 1px border in it packs neatly. However that's a bit of a weird formula to remember. The spritesheet packer usually does a pretty good job of working out how to fit in lots of different size images. So the best thing to do is (again) just ignore the specific size and choose whatever suits you best.

Conclusion

In the past, for technical reasons you might have to make some images a power-of-two size for best quality. With WebGL 2 this is no longer the case, and in fact sometimes using a power-of-two size image makes spritesheets less efficient!

WebGL 2 will arrive in Chrome 56, and you can test it now with Chrome Canary. Other browsers should follow soon, browser vendors are actively working on it.

So our new advice is this: don't worry about image sizes, use whatever you want!

Subscribe

Get emailed when there are new posts!