Dealing with Non-Power-Of-Two Assets

I am exploring running Phaser 3 games on a raspberry PI 3B+ and have run into a very unexpected problem: either I must run the game with the Canvas renderer or I have to make the game compatible with WebGL 1 (why is explained at the bottom of this post).

The canvas renderer, for various reasons, causes artifacts or just throws exceptions for a few of the games and that, combined with the fact that it is significantly slower than the WebGL approach, has led me to not prefer this option (at least not yet).

So my games need to support WebGL 1 (aka OpenGL ES 2.0). The biggest problem seems to be the lack of support for certain kinds of textures and in particular, non-power-of-two textures. The WebGL implementation for the RPI does not support the non-power-of-two extension.

Now, I’m an old school OpenGL programmer, I remember the non-power-of-two days vividly and they weren’t THAT bad, but we always just planned ahead. I’ve never had to take content that was already created and switch it to be a power of two. Right now I’m thinking of this:

  • Round up (possibly down) to the nearest power of two independently in each dimension
  • Compute a scaling factor for each dimension that will fix the inevitably broken aspect ratio
  • Apply that scaling in code in Phaser to fix the sprite

However, I’m wondering if there isn’t a better or simpler way to deal with this problem. Would it be preferable to pad the images with blank pixels up to the nearest power of two and if so, how would I then cut out the padding so it isn’t rendered? Is there a way to fix this problem without having to modify the code in addition to the assets?


For context as to why I’ve concluded that this is the situation on the raspberry pi:

  1. I tried loading our games in chromium running on a stock version of raspbian and they were horrendously slow. Those that tried to use WebGL pretty much just flat out didn’t work and switching to Canvas resulting is unacceptable slow frame rates.
  2. I read a few posts / thoughts about chromium on raspbian and the WebGL capabilities as well as ways to enable / disable certain WebGL things but no combination I found solved the issues, they mostly made them worse.
  3. I tried instead installing Chromium OS on the RPI (as provided by the good folks at Fyde OS) and this worked remarkably better! The Canvas version of the games ran serviceably well with no changes, much more efficient. However, some games simply refused to work in Canvas or had noticeable rendering artifacts in that mode.
  4. I tried switching back to the WebGL renderer and some games ran even BETTER in this mode. The GPU/OpenGL drivers for the RPI just seem to be sane and stable under Chromium OS when they are not under Raspbian. However, some games had huge black spots where textures/sprites should have been. I noticed a plethora of WebGL warnings about non-power-of-two textures and so I dumped a read out of the WebGL capabilities of the RPI on Chromium OS and found it was only WebGL 1.0 and lacked the non-power-of-two extension.

My adventures with Phaser 3 on the RPI are still in early days, but I think it should be a reasonable platform to target given what I’ve seen so far (though not for every game as it is seriously underpowered compared to any laptop/desktop alternative). Just looking for some ideas and help on where to go next!

Cheers!
Seth B.

You are making assumption that you can only render the whole texture at once. You don’t. I would recommend making a texture atlas (as big as the device allows, probably 4096x4096, maybe even more), and putting all your individual PNGs there. You can use e.g. Texture Packer for that. Phaser can load the generated json easily.
As a bonus, performance will increase too.