Before I begin delving into the mysteries of 3D graphics, I guess I should start off by explaining my reasoning behind writing this series of papers. Recently, I was trying to help out someone with a 3D problem and the more I explained to him, the more I realized he just didn't understand why I was doing what I was doing. This experience got me thinking back to when I was trying to learn 3D. I can honestly say, I understand his confusion.
The problem is that most 3D information available is either targeted at a specific technique or a specific API. This is great if you are an experienced 3D programmer, but it only adds to the confusion of a beginner. I propose that if a beginner can get a firm grasp on how a 3D engine works and why certain steps are performed, then he or she can develop a 3D engine in any API and incorporate the more advanced techniques as they are intended to be used.
These papers should help anyone trying to further his or her understanding of the 3D pipeline. While they're written for people who are new to 3D graphics, many programmers who think they understand 3D could use them. Remember this simple rule. If you can't program a 3D engine in software, you don't really know 3D.
All I expect from you is that you are an experienced programmer and that you have a basic understanding of high school math. All code examples will be written in C++, but keep in mind that the purpose of these papers is to teach you the fundamentals of 3D graphics, not to implement a specific engine in a specific language or environment. Code examples will be used sparingly and only when I feel they will help you better grasp a concept. As far as math goes, don't panic here. Obviously, math is extremely important in 3D graphics, but it's not as complicated as it appears. I will explain all the math used, and I will explain why it is used. Trust me here. The more you understand the math, the more you'll understand 3D.
Out of everything I have ever programmed, 3D is by far the most satisfying. There's just something about being able to create your own 3-Dimensional world that is beyond description. When you get your first cube to rotate on your screen, you'll know what I mean.
You're probably thinking, "That's great man. Where do we begin?" Well, before you can design a 3D engine, you need to know what it's supposed to do. We want to be able to model a 3-Dimensional universe, and we want to be able to look at that universe on our computer screen. These are two very different aspects of a 3D engine. For now, let's just look at how we can model an object in 3D.
As you may have guessed, we are going to have to use a coordinate system to model any type of object in 3D. Luckily, if you know anything about Algebra, this should come as second nature. Take a look at Figure 1. This is the standard Cartesian coordinate system used in high school Algebra. Using this system, you can define a point anywhere in 2D space.
Now, all we have to do as add a Z-axis to this system and we can define a point anywhere in 3D space. It sounds simple enough, but there is a bit of a catch. The positive Z-axis can point either in or out. When the Z-axis points in, it's called the Left-handed system. When the Z-axis points out, it's called the Right-handed system. If this sounds confusing, take a look at Figure 2.
You can choose either the Left-handed system or the Right-handed system, but keep in mind that your choice will affect some of your math later on. I will be using the Left-handed system throughout these papers. Generally, game programmers choose this system because it is easier to conceptualize the positive Z-axis pointing into the screen.
Now that we have a coordinate system to work with, let's start seeing how we can define objects in the system. There are three basic primitives we are going to use - points, lines, and triangles. Let's discuss each of them separately.
A point is the simplest primitive there is. Any position in 3D space can be defined by a point using three values (x, y, z). While this should seem obvious, make sure you understand this before you move on.
As in 2D space, a line in 3D space is defined by two unique points. Take a look at Figure 3b. Here, you can see an arbitrary line defined by two points. Before you go, "Yeah, yeah, I know what I line is," notice that since the line is defined only by points, you can change the line by simple moving one of these points. This is a very important concept to understand, since later on we are going to move everything in our 3D universe by moving individual points.
The final primitive we are going to look at is a triangle. Triangles will be the heart and soul of our 3D engine since all of the objects we are going to build will be modeled using triangles. The reason we use triangles instead of more complex polygons is because triangles have a lot of implied characteristics that other polygons do not. First, a triangle is guaranteed to be coplanar. This is obvious when you realize that a plane is defined by three points, and so is a triangle. Second, a triangle is guaranteed to be convex. If you are unfamiliar with this term, look at Figure 4. A convex polygon is basically a polygon with no "dents" in it. The reasons why this is important will become clearer later on. For now, just accept this as a nice feature of triangles.
You may think that using only triangles is too limiting., but it's not. Any coplanar polygon can be broken down into triangles. This is called triangulation. In fact, most 3D accelerator cards work only with triangles, so by using triangles natively in your engine, you can work at a level better suited for these cards.
Today, we began our adventure into the world of 3D graphics. We covered the basic coordinate systems used in 3D, and the basic primitive types used in those coordinate systems. If anything seemed fuzzy at all, please go back a reread the article. If you don't completely understand these concepts, you won't have a prayer to understand anything further. If you think that I didn't cover enough, that was deliberate. 3D Graphics is a complicated subject. I don't want to give anyone more then they can handle at once.
Next time, we will begin to look at some of the math needed to work with 3D graphics. Once we have that down, we'll learn how to use some of that math to move our points around in our universe. Finally, we are going to begin to think about how we can use points and triangles to represent an object in 3D.
Definitions Used In This Article
Concave Polygon -- A concave polygon is a polygon with "dents" in it. More specifically, it is a polygon where you can draw a line segment between at least two vertices without the line crossing over the polygon.
Convex Polygon - A convex polygon is a polygon with no "dents" in it. More specifically, it is a polygon where you cannot draw a line segment between at least two vertices without the line crossing over the polygon.
Collinear - A group of points are collinear if they are all located on the same line
Coplanar - A group of points are coplanar if they are all located on the same 2D plane.
Left-handed System - The 3D coordinate system defined with the positive Z-axis pointing inward, behind the XY plane.
Right-handed System - The 3D coordinate system defined with the positive Z-axis pointing outward, in front of the XY plane.
Triangulation - The process of breaking up a complex polygon into its triangle subparts.