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: