Tuesday, 10 June 2008

Power of 2 textures.

The artists are told time and time again that they can only have power of two textures. Do you know why?

Simple bit shifting will get you any of the valid texture sizes:


{ 1,2,4,8, 16,32,64,128, 256,512,1024,2048, 4096,8192,16384,32768, 65536,... }

What's so special about these values? Their ability to be simply masked for wrapping and tessellation. How is this possible?

take any of the numbers on the list, their binary representation has one and only one bit set (because they are the 0th bit (1) shifted up by n) because of this, if you take one away from them, they become all the ones up to and excluding their own. e.g.

8 = b1000 and 7 = b0111
256 = b100000000 255 = b11111111

this is useful because if you use these bits as a mask, you are effectively doing a safe modulus on the incoming value (as mentioned in a prior post)

if the textures are all power of two, then the texture look up engine needs only apply a mask to find the texel address for a wrapping texture.

consider a large square polygon with uvs { 0,0,4,4 } these are floats, and 4 represents 4 * pixel width/height of the original image. At some point on the polygon the uv is going to be outside the range of simple unit texture look up. If we look at one random part, say { 2.5, 0.5 }, we can see that the vertal (V), has a safe looking value, but the horizontal (U) is at 2.5 units. The base image in our demo is 32x32 pixels, when the rasteriser comes across this value, it doesn't look up the texture coordinate at { 80,16 }, it firstly takes the pixel width and height, makes masks and then ands with them on any texture look up. "80 & 31 == 16", so it actually looks up the texture colour at {16,16}.

No comments: