UE5 Tutorial: Power of Two and Mips
Hey everyone, Zach here!
In this tutorial post we will discuss the Power of two (no relation to the one in Star Wars) and Mips (or Mipmaps). This is a simple topic but one that I have not seen covered in much detail, even in my previous work on the survival series. So, we will cover what the power of two is, the rule around the use of power of two (focused on unreal engine of course), and Mipmapping. If these terms are completely unfamiliar to you, be aware that we are discussing textures and optimizing textures.
Part 1: What is the Power of Two?
Simply put, the power of two is any value that is equal to 2n. If you look at resolution sizes, for example, if we think about a 2k texture it is typically 2048×2048. 2048 is a power of two value; it is the value of 2 raised to the power of 11. A 4k texture is resolution (on either axis) is 2 raised to the power of 12 (or 4096).
Part 2: Obeying the Power of Two Rule
We don’t always need to obey the power of two guidance but we should. However, in this wild and wide world sometimes we end up with textures that do not obey the power of two rule (we will talk about this later in the post). But we should obey these rules ourselves, as it makes our lives easier.
But, not every side has to be the same value. The X and Y values of a texture does not need to be the same. As long as both sides use a value that is a power of two, we are obeying the power of two rule. But this does not mean we can have a texture 2×1024 (okay you could, in theory, and that would obey the rule – but it just would not work). In Unreal Engine (both 4 and 5), the ratio needs to be one of the following: 1:1 (square), 1:2, or 1:4.
Part 3: Why should this rule be obeyed?
There are three reasons for the use of power of two in textures today. Unreal engine can only Mip textures that that obey the power of two rule (including the ratios listed above). The other reason is that some graphics cards (though many of these are older) simply require that textures be in a power of two to do basic optimization of the streaming budget. The final reason is that it guarantees multi-platform support. All-in-all, this boils down to the simple idea of optimization.
This area of optimization is about texture mapping typically. And in Unreal only textures that conform to the power of two rule (as listed above) will have mipmaps.
Part 4: What are Mips/MipMaps?
Now before we jump into mips, I would strongly recommend reading up on the Texel Density Rule (and likely I will do something on this in the future) in relation to this topic. Having said that, I am going to disregard the Texel Density Rule when I discuss mips.
Let’s say for a moment you have a 4096X4096 texture on a large object (large as in takes up a fair amount of screen space). Let’s say, for the sake of argument, it is the body of a vehicle, and, in this example, we are working an open world game. When I am right next to vehicle, I might want to have all the finer details a 4k texture offers (like I said I am ignoring the Texel Density Rule for this). But do I need that same level of detail when I am 2 blocks away from the car, or when the car is using a LOD2 or LOD3? No. Instead, Unreal will apply a lower resolution textures (moving down the power of two values; e.g., 2048, 1024, 512… and so on) as we move the camera further away. These lower resolution textures are Mips.
Simply put Mips or MipMaps are pre-calculated sequences of textures are lower resolutions. Yes, it does mean that there is a greater cost of memory per texture, but it lowers our texture streaming requirements as well. In addition, they improve image quality over greater distances.
If we take a look at a texture (used in the survival game tutorial) we can see that all resolutions are a power of 2 value (in this case 2K textures) and that there are 12 mips. As 2048 is 2 to the power of 11, it makes sense that there are 12 mips (remember there is 2 to the power of 0, which is 2). The number of mips is determined by the resolution of the texture (e.g., 2 to the power of 11 has 12 mips, 2 to the power of 10, has 11 mips, etc.) The one extra (you will notice that our textures that violate the power of two rule all have 1 mip) is the initial image itself.
Part 5: Solving Violations of the Power of Two
Some textures may violate the power of two. I have included two textures for you to experiment with to follow the rest of this section. In one case the power of two is violated on one axis, in the second case it is violated on both.
One axis of the above image is a value that is a power of two (384 X 256).
In this case neither axis conforms to the power of 2 (2000 X 1333).
Now, let’s say we want these images to mip. We have have a way, via Unreal’s built-in features to help us to generate mips. If we open any texture in Unreal, under “Texture” on the details panel (on the right by default) there is a setting called “power of two mode.” If you texture obeys the power of two rule, then this setting will do nothing.
Before we continue something important to understand about the power of two mode: this features does not stretch the texture itself. Rather this feature extends the ‘canvas’ the texture is on (leaving blank places around the image).
First, we have pad to the power of two. This will extend the ‘canvas’ (think photoshop canvas if you have that experience) to the nearest power of two for any side that does not obey the power of two. So, let’s take a look at the image where one side obeys the power of two and see what happens when we apply this setting.
Notice before we apply the setting, that there are no mips. Also take notice of the texture itself.
Now when I apply the power of two mode we get:
Notice it pads the side that was not a power of 2 (384) to the next highest value that is a power of 2 (512 in this case). Now, initially it did not create mips, as the default for the “Mip Gen Settings” was not to generate mips. When I changed that setting to “From Texture Group” and had the padding on, it generated 10 mips. Let’s repeat this with the other image.
Again, notice that this image violates the power of two in both the X and Y axis and has 1 mip. But when we apply the pad to power of two (and update our Mip Gen Settings) notice it pads out both sides to the nearest power of 2 for both sides and generates 12 mips.
Next, there is pad to square power of two. This method will stretch the ‘canvas’ so that it is a perfect square. However, this means that if one side obeys the power of two rule and is smaller than the other side (as is in our case), it will raise both sides to a power of two value. It will pad it out to a higher value though. So, let’s repeat this process with the two textures again, starting with the texture that has one value that obeys the power of two rule.
Notice now when we pad to square power of two, as stated, both sides are padded out to the power of two. This is because the side that obeyed the power of two rule (256) was smaller than our other side (384) and the next nearest power of two value up was 512).
Now, let’s repeat this for our other texture.
You’ll notice, hopefully, that it is about the same as using the other approach (at least with this image).
In general, I would recommend using pad to square power of two.
Part 6: Notes
- Do not use mips for UI elements.
- Square textures (ratio of 1:1 for power of two) are more efficient in usage of memory (at least in unreal).
- Square textures (when not using a power of two texture from the start) are generally better compressed
Alright, that covers everything I wanted to address in this blog post. I hope to see you in the next blog post (or tutorial video). And, as always, I hope you have a wonderful day!
Recent Comments