61
\$\begingroup\$

Why are the resolution of textures in games always a power of two (128x128, 256x256, 512x512, 1024x1024, etc.)? Wouldn't it be smart to save on the game's file size and make the texture exactly fit the UV unwrapped model?

What would happen if there was a texture that was not a power of two?

Would it be incorrect to have a texture be something like 256x512, or 512x1024? Or would this cause the problems that non-power-of-two textures may cause?

\$\endgroup\$
6
  • 9
    \$\begingroup\$ Your other examples are also powers of two, just not the same power of two. The powers of two makes the texture optimized for the graphics hardware. \$\endgroup\$
    – House
    Mar 26, 2012 at 0:57
  • 1
    \$\begingroup\$ @Byte56 I think he means 2^n x 2^n texture, where n varies from 1 to infinite. (Not really infinite.) \$\endgroup\$
    – Robin
    Mar 26, 2012 at 10:54
  • \$\begingroup\$ Also note that powers of two have the benefit of making mipmaps trivial. \$\endgroup\$
    – Pubby
    Mar 26, 2012 at 13:30
  • \$\begingroup\$ Because the texture normally wraps (although you can choose this in a custom shader) you don't need to waste any space, simply wrap your polygons uv coordinates around the edges and you can make use of the available space much more readily. If you haven't got a pressing need its safest to stick to width=height=2^n textures because it will allow for a wider range of hardware at the cost of a slightly more complicated uv layout. \$\endgroup\$ Mar 27, 2012 at 11:18
  • \$\begingroup\$ They are not always powers of two. \$\endgroup\$
    – Almo
    Sep 26, 2016 at 22:56

7 Answers 7

55
\$\begingroup\$

Why are the resolution of textures in games always a power of two (128x128, 256x256, 512x512, 1024x1024, etc.)?

As Byte56 implied, the "power of two" size restrictions are (were) that each dimension must be, independently, a power of two, not that textures must be square and have dimensions which are a power of two.

However, on modern cards and which modern graphics APIs, this "restriction" has been relaxed significantly such that textures dimensions can be, within reason, just about anything you like. However:

Wouldn't it be smart to save on the game's file size and make the texture exactly fit the UV unwrapped model? What would happen if there was a texture that was not a power of two?

By ensuring the texture dimensions are a power of two, the graphics pipeline can take advantage of optimizations related to efficiencies in working with powers of two. For example, it can be (and absolutely was several years back before we had dedicated GPUs and extremely clever optimizing compilers) faster to divide and multiply by powers of two. Working in powers of two also simplified operations within the pipeline, such as computation and usage of mipmaps (a number that is a power of two will always divide evenly in half, which means you don't have to deal with scenarios where you must round your mipmap dimensions up or down).

It's true you "waste" some space this way, but the extra space is usually worth it for the tradeoff in render performance. Additionally there are techniques, such as compression or packing multiple images into a single texture space that can alleviate some of the storage waste.

\$\endgroup\$
9
  • 13
    \$\begingroup\$ "It's true you "waste" some space this way, but the extra space is usually worth it for the tradeoff in render performance." - About ten years ago I worked at a studio that was porting a PS2 game over to the XBox. While the PS2 doesn't technically support non-power-of-two textures, you can, in some cases, kind of force it to do so with a little clever manipulation and no speed loss. The XBox, on the other hand, completely did not support them. The end result is that despite the XBox having almost twice the RAM of the PS2, we had to downsample some of the textures in order to fit. \$\endgroup\$
    – ZorbaTHut
    Mar 26, 2012 at 6:01
  • 2
    \$\begingroup\$ I'm having a hard time finding a citation, but I have read previously that JPEG images should be at multiples of 8 for maximum efficiency, as anything outside of that still requires an 8x8 block. \$\endgroup\$ Mar 26, 2012 at 7:07
  • 3
    \$\begingroup\$ @salmonmoose: Correct; JPEG compresses each block of 8x8 independently and will pad blocks on the edge. But that's unrelated to this question. \$\endgroup\$
    – MSalters
    Mar 26, 2012 at 11:27
  • 2
    \$\begingroup\$ JPEGs are encoded in 8x8 blocks, yes. That's not really an efficiency consideration however. And it's not necessarily a power of 2 either. :) \$\endgroup\$
    – Kylotan
    Mar 26, 2012 at 11:28
  • \$\begingroup\$ An Example is on Android, where often non-poweroftwo textures result in white textures. \$\endgroup\$
    – user717572
    Mar 26, 2012 at 14:40
18
\$\begingroup\$

Why are textures always square powers of two?

Textures are not always square nor are they always powers of two. The reason why they tend to be powers of two is usually to increase compatibility with older video cards that imposed that restriction. As for non-square textures, that's not usually a problem. To summarize:

  • Textures typically don't need to be square - although DirectX does have a D3DPTEXTURECAPS_SQUAREONLY capability but I've worked with non square textures even in older hardware with no problems.
  • Textures should be powers of two because many older graphical cards still require it. The reason for that restriction was so that they could perform some optimizations to the texture mapping operations. Most modern graphic cards don't have this restriction either.
\$\endgroup\$
2
  • 14
    \$\begingroup\$ It should be noted that by "older graphical cards" he means stuff made before 2006 or so. \$\endgroup\$ Mar 26, 2012 at 1:14
  • 1
    \$\begingroup\$ @NicolBolas Thanks, I was actually trying to find some references on that point. \$\endgroup\$ Mar 26, 2012 at 1:18
9
\$\begingroup\$

It relates to graphics card optimizations. They've been designed to process them in that way. Most cards these days will allow you to load textures with dimensions that are not powers of two, but it will likely have a negative impact on performance. There is a good chance that when it loads it is actually going to be converted costing you load time and not saving any memory. Non-square textures are generally OK, as long as both their dimensions are powers of two.

One way of dealing with odd size textures is using a Texture Atlas. Basically, you place multiple textures together into a single texture and use the texture coordinates of your vertices to reference the particular image you need. This comes with additional performance benefits as well, because it allows to avoid state changes. A common use of this is placing all of the elements of the interface into a single texture, meaning that if you have batched up your interfaces vertices into a single buffer object, you can draw the whole thing with a single call, rather than switching textures many times and making a separate draw call for each one.

\$\endgroup\$
8
\$\begingroup\$

Graphics hardware is optimized for matrix operations, fragment operations and vector operations. Simply put square matrices are easier to deal with, as calculations may be done in blocks( called fragments ), hardware is optimized for block operations, which is why there are things like file buffers, the RAM blit does not blit to disk until a block has been populated. The same is true of graphics memory.

The frame buffer is composed of fragments which are square. For example in a screen with a resolution 800x600 and an RGB color space (0-255) there are 800x600 points with 3 bytes each channel there are a grand total of 3x800x600 = 1,440,000 bytes to address in the frame buffer. That means there are 1,875 addressable fragments that are 256x256x3 bytes. Because the texture data is square it makes it significantly easier to map from the GRAM matrix to the screen buffer matrix using bicubic scaling, where as if it wasn't square the bias for the longer side would take more time to calculate when it needed to be scaled.

Many graphics APIs will accept non square texture data, because they accept UV mapping coordinates as floating point data, however once it is sent to the GPU, padding is added to the texture data, because the actual proportions of the image do not change the mapping appears unaffected, however padding is added to the texture data, because the GPU likes addressing it as a perfect square.

So if a 100x1024 image is used, and image that is 1024x1024 is used which means 946,176 bytes are wasted. Even more so if compositing is to be done, because an alpha channel will need to be added in order to indicate that the padding data should not effect the composited texture.

\$\endgroup\$
1
  • \$\begingroup\$ This is an interesting explanation (titbit about square matrices) that is not found in the usual power of 2 answers (+1) - could you provide some citations if possible? \$\endgroup\$
    – Samaursa
    May 2, 2012 at 22:58
7
\$\begingroup\$

The problem is that some hardware has limited support for textures that don't have power of two dimensions.

For example, look at the bottom of http://msdn.microsoft.com/en-us/library/windows/desktop/ff476876%28v=vs.85%29.aspx and read footnotes 3 and 4 there.

3 At feature levels 9_1, 9_2 and 9_3, the display device supports the use of 2-D textures with dimensions that are not powers of two under two conditions. First, only one MIP-map level for each texture can be created, and second, no wrap sampler modes for textures are allowed (that is, the AddressU, AddressV, and AddressW members of D3D11_SAMPLER_DESC cannot be set to D3D11_TEXTURE_ADDRESS_WRAP).

4 At feature levels 10_0, 10_1 and 11_0, the display device unconditionally supports the use of 2-D textures with dimensions that are not powers of two.

\$\endgroup\$
0
\$\begingroup\$

Modern hardware can (finally) cope with enabling wrap modes on non-power of two based textures, however non-power of two textures still tend to waste GPU memory as they tend to get padded up along the width by some hardware specific amount (either to some tile size or rounded up to the next power of two size that contains the texture).

As this is hardware dependant and the vendors generally won't get into the specifics of these details, the safest thing to do is to continue to use power of two dimensions for textures, so as not to waste GPU ram.

\$\endgroup\$
0
\$\begingroup\$

Our digital world works with binary numeration then to multiplay or divide by 2 a value you can "move" a value to left or right i.e.

<<  Left shift      x = 5 << 1    0101 << 1     1010     10
>>  Right shift     x = 5 >> 1    0101 >> 1     0010      2

Work with values "power of two" is more easy for a CPU.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .