Life of a pixel: A primer on computer graphics

By Martin Splitt posted May 9, 2016

Every day most of us look at them in different amounts and sizes - on our phones, computers, TVs: Pixels.

But do you know how a bunch of ones and zeroes are turned into millions of bright dots in a variety of brilliant colours? This series of blog posts will shine a light on the little dots of colour.

Shine bright like a pixel

So the very first step is to get a pixel to light up in the desired colour. Each pixel is actual three single-colour pixels in red, green and blue. The combinations of these three colours allow us to create the entire variety of the colour spectrum that we need to draw graphics.

As the basis for all this, we are using a bunch of zeroes and ones - the infamous bits.

From Bits to Pixels via the GPU

The journey from these bits to pixels on screen goes through the Graphics Processing Unit (GPU) - one of its jobs is to take the numbers from memory and turn them into pixel information.

As an example, we'll be looking at a simple black white 2x2 pixel screen. Each pixel is exactly 1 bit: Zero means black; 1 means white.

In the picture above the screen is black, so our memory would contain all zeroes: [0, 0, 0, 0] If we wanted to make a diagonal white "line" from the top left to the bottom right, our memory would be [1, 0, 0, 1] instead, resulting in this picture:

Now the chances are high that you're not reading this on a screen that can only show black and white - but how do we get these colors?

The key is in the bits and the physical layout of screens: We're having red, green and blue and we mix these in different ratios to create all sorts of colours. Nowadays it's usual to have 256 shades of each color, giving us a total of 16.7 million colours.

So here we see our familiar 2x2 pixel screen, but this time we're having colours. Now each pixel needs to be expressed in three different colours: Red, green and blue - each colour has 256 shades (or 8 bits), so our memory looks like this: [ [255, 255, 255], [0, 0, 0], [255, 0, 0], [0, 0, 255]] for a white, a black, a red and a blue pixel. The way it was written down is just for our own convenience, the GPU will use three numbers per pixel, so it can be stored as a normal list of numbers.

The way we're representing colours isn't the only way of doing this. We're using 8 bits per colour channel (red, green and blue), so 8x3 = 24 bit colours, sometimes referred to as True Colour. Wikipedia has a great overview on the different colour depths.

After all, more colours mean more bits or simply put: More memory. So how much memory are we talking, actually?

If we consider a Full HD 1080p picture, we're having 2,073,600 pixels and 24 bit per pixel (3 byte), that makes a whopping 5.3 Megabyte - or 3.79 3.5" floppy disks.

Voodoo 2. Photo by Appaloosa

The card above is a 1998 "Voodoo 2" graphics card with a total memory of 8-12 Megabyte, but only 4 Megabyte to draw pixels on screen. So this card, while being very powerful at the time it was released to the market, is incapable of drawing a single 1080p frame, because it doesn't have enough memory available.

From pixels to lines and triangles

Now we know that we'll have to write into memory to get pixels onto screen, but how do we get from points to lines?

The problem boils down to: How to get from a line to a rasterized version of the line, that can be expressed as pixels.

With Bresenham's line algorithm we're getting this:

Once we're having this implemented, we're capable to draw lines between two points. As we gain the ability to draw a line, we can draw a triangle - and triangles are useful, because they can be used to approximate all other shapes.

Filling the blanks

Drawing lines is a bit limiting, so it would be nice to fill in the pixels between lines delimiting a shape.

The animation above shows one available algorithm, called flood fill.

This algorithm took 6 steps with 4 operations (comparing the color of the four neighbours) to fill a total of 9 pixels. This isn't very effective and can be improved by using another algorithm, such as scanline fill.