On the Back of a Napkin: Part 2

This article originally appeared in Dev.Mag Issue 3, released in May 2006.

Last week we went over some of the very basics of 3D graphics. This week we take a look at exactly what it is that vertices do for us and how they do it. We’ll cover some more abstractions and end up explaining some of the single-letter terms that kept cropping up a few years ago.

A quick recap

So, we know that to create a 3D scene on our monitors, we need triangles which are defined by three vertices. We know that most of the 3D data that is sent to modern cards is vertex information. But what exactly are these vertices?

The best answer is that a vertex isn’t a set thing. Modern cards have many formats of vertex that they recognize, and programmers use whichever format best suits the trick they’re trying to get right at the moment.

Position

Vertex positioning in 3D space

Vertex positioning in 3D space

The one thing that every single vertex will have is a position. After all, a vertex must describe a point in some space so that we know where our (eventual) triangle is going to appear. It’s this position that is turned into screen positions by our magic 3D cards. The actual format the position is stored in doesn’t make much difference, as there are many different ways to do this. Typically vertices store x, y and z values (because we can describe 3D space using three axes, go look it up) but they also store a fourth value, w, that is pretty cool for lots of mathematical reasons. Honest.

Colour

Vertices may or may not have some kind of a colour value, it depends on what a programmer or artist wants to happen. Vertex colours can be used to tint models, Diablo style. In 3D engines that use Vertex Lighting (You remember Quake 2 and 3) the vertex colour is determined by the interactions of the different lights in the scene.

Texture co-ordinates

Ah, textures. Textures are very important in 3D graphics. That’s why 3D cards have such large amounts of RAM and why we need to be able to send data to them really fast: Textures are big. But textures don’t store any positional information, so we need to know where on a texture a vertex is. To do that vertices store a texture position (they don’t store which texture they point to, that’s handled by the engine so that different textures can be used if needed) but storing the individual pixel x and y values from the texture image wouldn’t make much sense, so we use U and V scales in which 0,0 = the top left corner of the texture and 1,1 = the bottom right corner. The 0-1 scale is used so that textures can be different sizes without “breaking” the vertex.

Vertices can store other data as well, but we’re not going to go into that kind of detail now. Something else to remember is that vertex shaders operate on vertex data, so some programmers prefer to add their own data to vertices that are going to be processed by their vertex shaders, but we’ll cover that in another article.

Interpolation

Not such a big word

Not such a big word

Great, a vertex provides us with a whole ton of positional information, but it’s still an abstraction that’s not tied to our final image on screen. How does the point based information in a vertex get “spread” across the rest of the triangle to fill it with colour or a texture? The answer lies in a simple technique called Interpolation.

To interpolate between two values simply means to put each value on either end of a scale and to combine those values in different amounts based on where you are between them. In 3D graphics, we tend to use interpolation twice when drawing a triangle: First we interpolate all the values we need between the three vertices to create the edges of our triangle; Then we interpolate horizontally over the triangle to get the values at each pixel in the triangle. This process of determining the actual pixel colours is called Rasterisation and determines the Fill Rate of your card (ie: How many pixels your card can colour in a second).

So, what have we learned?

  • Vertices tell us where things are.
  • Programmers can pick what they want to store in vertices.
  • Vertices will always have a position.
  • Texture coordinates link vertex points and texture pixels.
  • Interpolation “spreads” the data in vertices out to fill triangles.
  • Colouring the actual pixels onscreen is called Rasterisation.