Texture Generation
The XOR Texture
Introduction
The XOR texture is a very easy to generate texture that looks fine. However, it's so overused that it's not a good choice to use in in a demo or intro release. It isn't useful for games either, unless you want some fancy floor tiles. What it's useful for, is for testing a texture mapper you just wrote, in case you want to quickly test out a pattern without having to load an image file or write more complex texture generation code.
This is an extremely small article, but the XOR Texture just couldn't be left out in a series of texture generation articles.
The XOR Texture
The XOR texture is simply generated by xor-ing the x and y coordinate of the current pixel. The '^' operator in C++ is the XOR operator.
int main(int argc, char *argv[])
{
screen(256, 256, 0, "The XOR Texture");
for(int x = 0; x < w; x++)
for(int y = 0; y < h; y++)
{
Uint8 c = x ^ y;
pset(x, y, ColorRGB(c, c, c));
}
redraw();
sleep();
return 0;
}
|
That's it, if you run it, you see the XOR texture:
There are 3 things you should keep in mind though:
1) The sizes of the texture should be a power of two, if they aren't, the texture doesn't look as good:
2) Color component values range from 0 to 255. The maximum color value generated by the XOR operation is the same as the dimensions of the texture if it's size is a power of two. So if the size of your XOR pattern is smaller than 256, for example only 64, it'll be too dark (image on the left). Multiply the color with 4 to make it bright again (image on the right):
3) On the other hand, if the size is larger than 256, for example 512, you have to make sure the color is limited to a maximum value of 256. You can either modulo divide it through 256, but then it isn't a real XOR pattern anymore. Better is to divide it through 2. In any case, using a XOR texture larger than 256x256 doesn't increase the quality because there aren't enough distinct color values, unless you're using a color mode that allows more bits per channel. But who'd want to generate a 1024x1024 XOR texture anyway.
The XOR operator takes the binary values of both integers, and does a binary XOR on every two corresponding bits. XOR or eXclusive OR returns 1 if both bits are different, and returns 0 if both bits are the same: "Bit a is 1 OR bit 2 is 1, but not both". In other words, it applies the following truth table to every two corresponding bits:
XOR | ||
Bit_a | Bit_b | Result |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
This is done on every bit of the integer, creating the many possible resulting values.
For example, 5 XOR 13 = 8, because in binary 0101 XOR 1101 = 1000.
Colors
You can also try the XOR texture with different colors, by using different value for R, G and B. For example:
int main(int argc, char *argv[])
{
screen(256, 256, 0, "The XOR Texture");
ColorRGB color;
for(int x = 0; x < w; x++)
for(int y = 0; y < h; y++)
{
Uint8 c = (x ^ y);
color.r = 255 - c;
color.g = c;
color.b = c % 128;
pset(x, y, color);
}
redraw();
sleep();
return 0;
}
|
You can even use the xor value as hue for the HSVtoRGB function...
int main(int argc, char *argv[])
{
screen(256, 256, 0, "The XOR Texture");
ColorRGB color;
for(int x = 0; x < w; x++)
for(int y = 0; y < h; y++)
{
Uint8 c = (x ^ y);
color = HSVtoRGB(ColorHSV(c, 255, 255));
pset(x, y, color);
}
redraw();
sleep();
return 0;
}
|
AND and OR
The AND and the OR operator also generate a similar texture.
The XOR operator returns 1 if both bits are different:
XOR | ||
Bit_a | Bit_b | Result |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 0 |
The AND operator, only returns 1 if both bits are 1 (bit a AND bit b are true)
AND | ||
Bit_a | Bit_b | Result |
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 0 |
1 | 1 | 1 |
The OR operator returns 1 if any or both of the bits are 1 (bit a OR bit b is true)
OR | ||
Bit_a | Bit_b | Result |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 0 | 1 |
1 | 1 | 1 |
The AND operator is denoted '&' in C++, and the OR operator '|', replace the '^' operator with those to use the new operators. Here's the result of XOR, AND and OR respectively:
It makes sense that the AND texture is darker, because it returns 1 only in a single case. The OR texture is brighter, because it returns 1 very often. The sum of the XOR texture and the AND texture is the OR texture.
Conclusion
It was shown how easy it is to create a XOR texture, which makes the XOR texture useful to test if a texture renderer is working. However, it's not suitable for applications such as art or games.
Here, the XOR pattern was used as a 3D texture (x ^ y ^ z) to test if a planet texture renderer was working correctly: