I see most UI interface work in UE4 and every other game using power by two for their icon formats.It is related to MIP mapping. But I only have a vague understanding of this matter. If I create images for UMG use, flat images displayed on the HUD or user interface, do I have to use power by two to prevent any texture anomalies? Or can I simply use 100x100 pixels instead of 128x128?
Bitmaps in the game are converted to mipmap formats:
It has to do with how textures are stored and addressed in memory, not just mipmapping.
Images are a data structure of rows and columns of bytes, corresponding to pixel locations and colors, though in memory the whole thing is one long, flat, line of bytes.
So to paint a pixel you need to go to a certain offset in that string of bytes, read the data there, do some processing, and display it to the screen.
Normally this is done in a top to bottom, left to right order (hence why the 0,0 coordinate is the top left). But to properly render an image you need to know when to shift to the next line.
This is fairly straight forward, as each row starts N times the Width of the image.
Multiplication is a fairly simple operation, but when you have to do it millions of times a second it can add up, and become a bottleneck.
Also if you want to go backwards (like say, find the pixel above and below the current one so you can do a bilinear filter operation), you’ll need division, which is a fairly costly operation.
However, if your row dimensions happen to match your mathematical base you don’t have to do multiplication, you can just add on the base and switch rows.
For a base 10 example: Your image is say 10 px by 10 px. row 1 is 00-09 row 2 is 10-19, row 3 is 20-29… see the pattern? What about 100x100 (or 10^2 x10^2) each row starts on N times 10^2 (0, 100 200, 300 etc), so you’ve just changed your ability to address a given pixel from a multiplication to an addition. Much simpler.
It gets better in binary, as there is an operation called a bitshift. This is when you take a string of bits (lets use 00100 to start with), and actually shift the contents to the left or right. (Left shift = 01000, rightshift = 00010) Very simple operation, but in binary this is equivalent to multiplying or dividing by a power of 2. (00100 = 4 01000 = 8 (4*2) 00010 = 2 (4/2))
What this means for image addressing is you can very quickly shift between rows, and even offsets in an image to sample pixel data, which is very important for realtime applications. This optimization is less mandatory with the power of modern hardware, but its still very useful.
As for mipmapping: This setup also makes that addressing scheme simple as each subsequent map will be one right shift smaller than the previous, making for additional simple routines to change mip levels quickly.
As for UI elements: You do not have to use power of 2 textures at this point in time if you do not need mipmaps, however unless you have a very compelling reason to not use a power of 2 dimension, I’d suggest sticking with it. Even leaving a bit of blank space at the edges if you need. Hardware and software now can render non power of 2 textures, but they are still built to handle power of 2 textures far more efficiently.