Optimization Story #1: The Reason Why We Must Use the Power of Two for Textures

ARBEON Co., Ltd.
Arbeon
Published in
10 min readJan 10, 2023

Hello! Nice to meet you!

I am Nate, the Technical Artist in charge of solving all graphic issues in the Arbeon application and giving life to it.

Have you ever experienced when your file sizes have gone bigger than the original file when using texture files or UI images in game engines?

And I’m sure the build file that’s become larger than you expected has given you a lot of trouble at least once.

In this first series of the optimization post, I’ll be revealing the secret behind the texture size used in game engines.

Optimization Story #1
The Reason Why We Must Use the Power of Two for Textures

Introduction

Regarding game productions, it’s generally true that the file format that takes up the biggest storage in package builds is texture (for 3D meshes, including the UI). Moreover, the number of files is also incomparably greater than the other formats. Therefore, using a large number of texture files takes up huge disk space for installation and requires a large amount of memory. Once an activity surpasses the specification and limit, the app could even crash and force quit on its own.

[ App crash — Cases like this happen when a certain activity uses beyond the allowable RAM ]

To solve this issue, many competent engineers came up with various methods to maintain the texture quality and reduce the size. To make use of the optimization function, a “promise” must be kept. That promise is saving the images in the power of two (POT). In this blog post, I’ll talk about why images are saved in POT sizes in game engines.

But before we get to that, allow me to briefly mention how our computers operate. Any person in the modern world uses smart devices or computers at least several times a day. And we use them to play games, browse the internet, watch videos, listen to music, and do work. All of these activities are done in the binary method composed of 0 and 1.

So there is a reason why those smartphones and computers are called “digital devices.” It’s because the digital system only has On (1) and Off (0) functions. And let’s travel back about 50 years in the past to better understand the background of effective usage for the binary system.

[Representative of 8-bit computers — Left: Apple II Right: Nintendo Family Computer (a.k.a. Famicom)]

The 8-bit computers and games received avid attention in the late 1970s, and the specifications of those devices will make you gape in surprise! There’s such a major difference between them and the devices now.

[ Specifications of APPLE II & Nintendo Family Computer ]

Their prices weren’t low either.
In 1977 when APPLE II was released, the price for the device was about 1,200 dollars. For the Nintendo Family Computer, the price was 14,800 yen at the time of its release in 1983. Considering the average wage of workers during late 1970s to early 1980s, not everyone had the luxury of getting their hands on the devices. Among them, the memory boasted a soaring price.

The personal computers and game consoles targeted ordinary consumers, so the production cost had to be cut down. This meant that the number of components needed to be reduced. So that was how the binary number combination came to be, which aimed to express the text and graphics in a limited environment and screen. One of them is ASCII, which uses 7-character combinations of binary numbers (128 different combinations).

[ ASCII Binary Character Chart ]

For example, it was promised that the code of a lowercase “a” would be 11000001, while the uppercase “A” would be 10000001. Like this, since ASCII and ANSI, which are defined to represent text, the most basic element to be printed on a computer screen, are computed by two raised to 8th power, the usage of binary numbers of 8 digits creates the unit of 8-bit.

The 8-bit computers most distributed to the public had the capacity to process 1 Hz, or 28 size of information (256 combinations), at once. Following this, the memory capacity for temporary saving and quick data usage was produced to fit the power of two.

[ Memory capacity and its binary combinations ]

Through this, you will see that the capacities of the memory devices being sold in the market are in the standard of 8, 16, 32, and 64 gigabytes.

Main Body

Understanding the Color and Bit

The binary combination can save or express text, but it can also be used to express colors. For a single bit, or a 1-bit, there are only 0 and 1. In case 0 is set as black and 1 as white, expressing the color of black and white is possible. This is called a 1-bit color.

Let’s try to increase the numbers.
²² (2-bit color palette) is 4, so it uses 4 colors. Cyan and magenta are included on top of the black and white, which were defined a while ago. But it’s not always the case that cyan and magenta are applied. Other colors can be saved in the palette, and users can exchange the color palettes whenever they need.

²³ (3-bit color palette) has 8 colors, so on top of the 4 colors mentioned above, red, green, blue, and yellow have been added. Not a lot of devices applied the 3-bit color system.

And by the time ²⁴ (4-bit color palette) was developed, 16 colors were made available, and it was only since then that the basic colors of the image could be expressed.

²⁸ (8-bit color palette) has 256 colors because it’s two raised to the eighth power. This color range was widely used from the 1990s to the early 2000s, and the game we’re all familiar with — Starcraft — was able to render such high-quality gameplay with just 256 colors.

What about now?
The 160,000 colors, commonly called the “True Color” palette, have become available by turning each red, green, and blue channel into an 8-bit palette and multiplying them. It’s also called 24-bit color because there are three 8-bit channels.

Some graphic cards support the function to create a total of 30-bit color (10-bit color for each R, G, and B channel). More colors could be expressed than that, but because they are expensive, they’re mainly needed for expert usage.

Then what about the transparent image? Since an 8-bit transparent channel (256 stages) is added to the 24-bit color we looked at a while ago, it’s called 32-bit color.

Image Size Calculation Method, Sizes Stored in Memory, and the Reason for Applying POT

Since we have delved into the process of how the color is expressed in the number of bits, let’s look at how an image is saved in the memory. Calculating the size of an image file is actually not very difficult.

[ The general calculation method of image file size ]

  • Image file size = width pixel x height pixel x number of channels used

* Please take note that the above calculation method is only applied for
uncompressed BMP files, not compressed formats like JPEG or PNG.

For instance, in the case of a 32 x 32-pixel image with a transparency (Alpha) channel applied to the true color (red, green, and blue), it’d be 32 x 32 x 4 (R, G, B, and A) = 4,096 bytes = ²¹²

You will notice that the pixel size of the width and length of the example image is an exponent of two.

It would be perfectly saved in the video memory, which is standardized to the power of two. But differences do exist depending on the image programs, and in particular, the file size and the following memory size will vary when used in game engines. So please just take note of that.

Now, let’s look at the example of an actual file.

If you import the image (180 x 180 pixels) in Unity, you’ll find that the pixel is automatically changed to 128. This is because the non-power of 2 in the image setting of Unity is, by default, set to ToNearest. In other words, the value automatically changes to the closest exponent of two.

To be more specific, the 180 pixels have been automatically changed to 128 pixels because it’s closer to 128 (²⁷) pixels than 256 (²⁸) pixels. Then what would happen in the case of a 200 x 200-pixel image?

You can see that the image has been changed to 256 x 256 (²⁸) pixels. Now, what do you think will happen if you don’t use the automatic change function for the non-power-of-two resolution and use the original resolution?

The vivid difference can be seen in the file size (That value would be applied during the build). In comparison to the size of the actual original file, you’ll see that it’s gotten bigger by four times.

And it’s a no-brainer to see that it had gotten way higher than when it was automatically converted to 256 pixels (42K). Like this, the images with the size of the power of two pixels are more efficient when the game engines or real-time graphic library is used.

There are several reasons for recommending the POT textures in game engines and why they must be used, but let’s look at some of the few cases below and find out.

[ Image compression options offered by Unity]

1. In the case of mobile platforms, two kinds of optimized image compression methods are generally used. One is ASTC, and the other is ETC format. The compressed format is properly supported only if the resolution of the texture is in the POT quantization.

2. The “MIPMAP” helps optimize the rendering by decreasing the resolution of the texture by stages as the game camera gets farther. And MIPMAP operates with utmost efficiency when it follows the POT resolution.

3. OpenGL, a computer graphics library, supported NPOT in version 2.0 (2004), but it was impossible during those times to use MIPMAP when a size image other than POT was used. And worse, it wasn’t rendered through graphic cards but only through the CPU. Certainly, it goes without saying that it caused serious visual errors and affected performance.

Conclusion

“Let’s opt for the appropriate compression settings of texture images, and reduce the build size and memory usage!”

The concept of POT texture is one of the products of optimization to actualize game or real-time graphic rendering. It’s the compound result of various fields, including math and physics, that seeks to achieve a more realistic and beautiful rendering in devices with limited performance.

But thanks to the hardware specification that advanced at lightning speed, the real-time graphics have become on par with pre-rendered graphics like videos. Unlike in the 2000s when event scenes in the middle of gameplays were in the form of a video, now, graphics for all situations are rendered in real time.

And just as the cost for the game graphics asset production has increased compared to the past, there are many instances of using equipment that’s as advanced as that used in film production. Despite that, however, the usage of POT texture remains unchanged. Since the software and hardware have been developed to fit the POT format, it has become a “promise” that can’t be overlooked when optimizing real-time graphics.

The performance that demands the quality of real-time graphics has gotten better, but it’s the same as in the past in the sense that the requirement level is “limited.” Even though a lot has changed, you can see that the fundamental method still remains the same.

Applying POT isn’t very hard, and all you need to be mindful about is when you’re exporting your final output.

The textures produced in the POT quantization offer wide alternatives when applying the optimization options in various game engines. And the size of the final build will get smaller depending on the selection of options, and it’s going to be a great merit for app users as well because it doesn’t strain the device when used.

Ref.

1. https://forum.unity.com/threads/npot-textures.54954/
2.
https://forum.unity.com/threads/disadvantages-of-non-power-of-two-textures.814542/
3. Youtube Channel :
about game play
4. APPLE II Image source :
https://ko.wikipedia.org/wiki/%EC%95%A0%ED%94%8C_II
5. Nintendo Family Computer Image source :
https://en.wikipedia.org/wiki/Nintendo_Entertainment_System

--

--