More than a texture patch? (Part 3)
In this part of the series we will go into more detail about how the color of a pixel is described and how transparent pixels are drawn in Gothic as well as what doesn't work so well.
First of all, the color of a pixel can be described by several models. The most common is the RGB color model, in which red, green and blue are used as primary colors. These color components are also referred to as channels. The colors are mixed additively, which means that all together result in white. You already know this type of color mixing from light in physics class. By the way, the paint box from art class works with subtractive color mixing, where all colors together result in black. In the computer, 1 byte is used per color channel, which in itself consists of 8 bits. Since each bit can have the values 0 and 1, a byte can have 28 = 256 different values. Since we have 3 color channels, with 1 byte each, we can therefore describe 2563 = 16,777,216 different colors.
To illustrate all the colors that can be described, I used a cube with the back side shown once and the front side shown once. If you like, you can also view the cube in 3D thanks to Scott Anderson and Ellen Hildrethauch from Wellesley College.
Anyway, to render vegetation like the leaves on a branch, we also need transparent pixels. For this, there is another color component, called the alpha channel. Ideally, 1 byte is also used for this, allowing 256 different levels from transparent to opaque. However, since the textures are compressed, usually only 4 or even 1 bit is available for the alpha channel. With gradients, you can see the differences immediately. With leaves, on the other hand, there is hardly any difference between 8 and 4 bits, while with 1 bit you can see the hard edges clearly.
To draw faces with alpha textures, there are two modes in computer graphics, named alpha blending and alpha testing. In alpha testing, a test or rather a condition is formulated which decides whether a pixel is drawn or not. Usually, the value of the alpha channel is used and compared to a threshold – in extrema whether it is 0 or 1. Alpha blending, on the other hand, draws each pixel and blends it with the already drawn image. There are several blending modes for different purposes. In our case, however, we would simply draw the pixel as it is. Basically, both techniques have their advantages and disadvantages, like display errors. With alpha testing, the pixels which meet the condition are always drawn opaque, although they might be semi-transparent. With alpha blending, intersecting surfaces lead to display errors, but these are usually not that noticeable.
Unfortunately, Gothic uses only 1 bit for the alpha channel and consequently draws the textures with alpha testing, which makes it impossible to display transparency gradients and soft edges.
Happily though, Gothic can indeed read compressed textures with 4-bit alpha. I therefore spent some time trying to teach Gothic how to do alpha blending. To my regret, these efforts were not fruitful. However, during my research I came across this blog article by Shawn Hargreaves, which describes a two-step process in the last paragraph.
The mostly opaque pixels of the texture will be drawn first with alpha testing and the others with alpha blending. The special thing about this is that the so-called Z-buffer is used differently in the two passes. I adopted the described approach and optimized it a bit more to reduce display errors.
The result is decent, but reduces the frames per second (FPS) by about a fifth, since many objects in the world are drawn twice. Since Gothic 2 can correctly handle alpha blending, I hope to get this feature working in Gothic 1 someday.
In the fourth part, things get misty, dark and also a bit spooky. But don't worry, Innos will be watching over us!