3D Math Primer for Graphics and Game Development

Fletcher Dunn, Ian Parberry

Mentioned 12

This book covers fundamental 3D math concepts that are especially useful for computer game developers and programmers.

More on Amazon.com

Mentioned in questions and answers.

I'd like to get an idea what kind of math is typically necessary for 3D game engine programming? Any specific math (such as vector geometry) or calculation algorithms (such as fast fourier transforms), or is this all abstracted away with DirectX/OpenGL so that highly complex math isn't really necessary any more?

For the most part linear algebra and computational geometry; Quaternions are used extensively and numerical analysis is necessary if you are working on a physics engine.

How much you'd use the stuff on a daily basis depends on what you are doing. If you are a graphics programmer, and therefore building the 3D graphics engine itself, then you would likely be implementing or maintaining implementations of class libraries and functions that actually do the math, so it would be relatively important to know the gory details. If you are using the library as client or working on another part of the game engine (AI, audio, UI, camera, etc.) then you will need to understand the math conceptually but you can certainly get away with not knowing how to implement a matrix inverse on a whiteboard off the top of your head.

Graphics APIs do not eliminate the need for someone to know this math; they are limited to drawing, so all the scene management and world simulation needs to be implemented outside the graphics API. Of course, there are middleware options there too but many studios roll their own systems.

There are a fair number of resources targeted at this market. For example, on Amazon there are books like 3D Math Primer For Graphics and Game Development, and there's probably a lot of stuff online too.

So, it's been a few months since I wrote this question, since then I've toyed with "raw" C++ D3D, The Ogre and Irrlicht graphics engines and lately Microsoft XNA. I've built a few 2D games (mostly replicas of old stuff like tetris, astreoids, etc.) and made some (very) small steps into the 3D world in the above mentioned technologies.

I have little to no trouble creating the actual game logic, abstracting away object interactions to allow me to plug in different forms of control (computer, player, over network. etc.), doing threading or any of the other stuff I'm used to from my day to day work - which feels perfectly natural to me. I messed around very little with HLSL and particle effects (very very basic).

But 3D math involving Matrices and Vectors (and Quaternions(?) in Ogre3D, are these really needed?)... really gets me, I can follow examples (e.g. the Learning XNA 3.0 book I bought from O'Reilly, which is an awesome book btw) and I understand why and how something happens in the example, but when I try to do something myself I feel that I'm lacking the understanding of this type of math to be able to really get it and make it work by myself.

So I'm looking for resources on learning 3D math (mostly) and some Shader/Particle Effects books. I would prefer resources that are pedagogic and take it slow above something like a doctors thesis on vector math which will be way over my head. The ideal resource would be something that demonstrates it all in D3D.

Fredrik - the short answer is that, yes, you must learn Matrices and Vectors as they are the mathematical underpinnings for 3D work.

While Linear algebra is definitely not doctorate-level mathematics, it will take a bit of work. To get started, check out this book on Amazon: it looks like it is exactly what you are looking for. I haven't read this particular book (the one I used in grad school is a bit out of date) but it is particularly well rated.

One other thing: there are various 3D modeling engines that do this work for you on the market. The most famous of these is arguably the Source Engine from Valve. You can use this Engine (built for HalfLife2 & CounterStrike) to create some pretty sophisticated games while working above the level of 3D modeling. In fact, one of the most popular games on the Steam network, Garry's mod started with someone just playing with cool things you can do with the Steam Engine. Here's a link to a site that provides tutorials for building your own worlds using the Source Engine in case you are interested.

I have had absolutely no trouble learning C++ and object oriented programming through books. However, I really want to head into 3D game development but I feel my math skills are pretty underdeveloped for this. I want to understand dot products, cross products, normals, vectors etc. I also hear calculus is very important for this too, aswell as linear algebra.

I also want to be able to understand how to implement fustrum culling, octrees, 3D lighting, etc. Because right now, when I follow tutorials for these things I feel like I'm just copying code without at all understanding the underlying mathematics.

Unfortunately the Computer Science program I did in College did not focus on math but rather programming, hardware, and networks. Therefore I have never taken a Calculus course.

What book would be ideal to understand these concepts?

Thanks

What I found very good and I'm still getting back to it from time to time to refresh things up is 3D Math Primer for Graphics and Game Development. Also regarding calculus and linear algebra I find very good for getting back ones college course memory the resources at Khan Academy... sometimes it puts a nice practical perspective on things and the guy has has a real talent at making the subjects fun and entertaining.

"OpenGL redbook" has some good stuff from a very applied perspective: http://www.amazon.com/OpenGL-Programming-Guide-Networking-Technology/dp/0321173481

Opposite end of the spectrum, if you want to be able to just sit down and derive your own solution to semi-abstract problems, this is a great linear algebra book: http://www.amazon.com/Linear-Algebra-Applications-Differential-Equations/dp/0471174211

"when I follow tutorials for these things I feel like I'm just copying code"

Its hard to replace the pressure of being forced to do math problems in a university setting ... you'll have to push yourself to reap the benefits, and relax with the desire of making something complex work in code. Pick something extremely simple, such as drawing XYZ axes and visualizing matrix transformations, and do it from math/scratch without any API calls.

I am not sure if my question title makes sense to you or not. I am seeing many cool applications which have cool animations/effects. I would like to learn how to use python to create this kind of GUI applications under Linux.

"cool animation/effects" like 3D wall in Cooliris which is written in flash and compiz effects with opengl.

I also heard of some python GUI library like wxPython and pyQT. Since I am completely new to python GUI programming, can anyone suggest me where to start and what I should learn to achieve and create such application? maybe learn pyQT with openGL feature? pyopengl binding? I have no clue on where to start. thank you very much for your time and suggestion.

By the way, in case if someone need to know which kind of application I am going to create, well, just any kind of applications. maybe photo explorer with 3D wall, maybe IM client, maybe facebook client etc...

http://techbase.kde.org/Development/Languages/Python

Many KDE styles use SVG and plenty of animation. The user can always change themes. I think you should be more specific about what kind of animations you want to do. I don't think 3D wall type affects really fall into the widget category that QT is. It sounds to me like you want to make a 3D interface for an application. If that is the case, you may want to look more into 3D engine type libraries used mainly in games. I know that some have excellent GUI widgets for programming game menus and the like. I guess you'd decide on your engine and the see if there are python language bindings. One of my favorite engines: http://irrlicht.sourceforge.net/links.html

Another thing you would want to consider is how you want to handle the window management. Do you want to make a full screen interface? Or is to to be windowed? Also how would such an application integrate into a 3D window manager or rather a window manager with compositing.

Edit:

In that case the qtopengl module is probably something to look into: http://doc.qt.nokia.com/4.6/qtopengl.html

I do recommend QT. It's clean and easy to use and cross platform. So your app could run on windows as well.

One thing you'd want to think about before hand is the type of FX you want to perform. For example, if you want to create a page curl type effect when renaming the image, you'd have to think about how to program that, or look for libraries/code snipets that do that math. 3D engines that are used in games often have a lot of support for those kind of typical FX or animations that you'd see in a game. If you use something like qtopengl, you'd need to think about this as well. qtopengl can pretty much only render. Think of it as a viewport. However, it is the correct approach to making a 3D application for the desktop.

Programming 3D applications is really interesting and fun. I enjoyed it a lot. However, don't get discouraged be the math. I recommend getting a book about it if you are serious. I liked this one: http://www.amazon.com/Primer-Graphics-Development-Wordware-Library/dp/1556229119

However, IIRC the examples are C++ which you may not be comfortable with. When you understand such mathematical concepts, it easier to think about how you would make a page curl type affect. Of course, if you find libraries or code that shows you how to do the math, that may be fine.

I have been trying to find some well presented and explained Vector and Quaternion resources recently to brush up on my 3D skills, and have been having some trouble.

Most of the resources I have found tend skip over the high-level reason that performing a particular operation is useful, and dives straight into jargon and proofs that tends to loose my attention rather quickly.

I have found that better explained has really good explanations of various math topics, however doesn't have anything for Vectors or quaternions.

Does anyone know of any high level Vector and/or Quaternion tutorials?

Get 3D Math Primer for Graphics and Game Development. It's not a free online tutorial, but I seriously doubt you could find any online tutorial that covers 3D math in such detail while still being very accessible and beginner-friendly. It's got the best coverage of quaternions that I've come across, and it also introduces all the mathematical formulas with a geometric interpretation so that you know how they relate to computer graphics.

Other than that, here's a good basic Vector Math Tutorial. For Quaternions there's the Wikipedia article and some other resources you could find with google, but they all seem too brief or tied to a certain technology. Again, just buy that book (or alternatively this one which covers more topics but spends less time on the basics).

I'm a hobbyist game programmer. I only do 2d games, no 3d stuff. I don't have a math background and lots of things are tripping me up like bullet projections and angles.

I took two college level Algebra courses at the local community college, but really disappointed. I got As in both, but really don't feel like I'm using any of it in my everyday 2d game programming and still stuck on angles/bullet paths, etc

I dropped out this semester to self study. The advisory at the community college said I want to be in Statistics for this and was really pushing me hard to enroll in that class. He said Statistics then Calculus I & II would get me what I needed.

I've been reading up a lot and not so sure on this. I think I should start with a a Geometry book and then move into Trigonometry? Is that the right approach?

Anyone suggest any good self-study starter books?

I got a lot out of "3D Math Primer for Graphics and Game Development". I know it says 3D but there is a lot of stuff in there for 2D. And the math is fairly simple linear algebra.

There are a few points here:

1) The statistics suggestion is a complete misdirection, and this advice should be completely ignored, along with the person who gave it to you. Statistics is an interesting topic, but not at all useful in game programming (except maybe for a few esoteric approaches to esoteric topics, maybe, like, drawing clouds).

2) (Not that you seem to but...) it's not uncommon for programmers to make the mistake of assuming that they can just learn everything on the job, but most science topics (including math) can not be effectively learned this way. With these, one needs a much more structured approach, building an elaborate structure of ideas, with each new idea built on top of the previous. You could certainly program games with a few equations that you learned to use from a game programming book, but it's unlikely you'd ever have the ability to solve problems that you hadn't already seen solved somewhere else.

3) The best way to get comfortable with math is to solve lots of problems, and not on the computer, but with pencil and paper. For example, you can easily write a program to test that sin2+cos2=1, but to prove it, you need to understand it.

4) Of the topics you'll need, trig is the most time effective place to start. Geometry would be a bit useful, but probably not so much. Another useful topic is linear algebra. Calculus is also useful for calculating trajectories that have acceleration (and gravity), but it's a much bigger topic and involves so many new ideas that it's probably a bit difficult to pick up on your own. Maybe for this topic it's best to try to glean a few useful approaches and equations.

Final suggestion: I recommend starting with trig, and use a book that gives concise explanations followed by lots of problems that are solved in the back. For example, Schaum's Outline of Trig for $13, would probably be a good choice. You don't need to solve a every problem in the book, but work them until you're comfortable, and then move on.

I am IT student and I have to make a project in VB6, I was thinking to make a 3D Software Renderer but I don't really know where to start, I found a few tutorials but I want something that goes in depth with the maths and algorithms, I will like something that shows how to make 3D transformations, Camera, lights, shading ...

It does not matter the programing language used, I just need some resources that shows me exactly how to make this.

So I just want to know where to find some resources, or you can show me some source code and tell me where to start from.

Or if any of you have a better idea for a VB6 project.

Thanks.

A software renderer is a very difficult project and the language VB6 is not indicated at all ( for a task like this c++ is the way.. ), anyway I can suggest you some great books I used:

  1. Shaders: http://wiki.gamedev.net/index.php/D3DBook:Introduction_%28Volume%29
  2. Math: 3D Math Primer for Graphics and Game Development

There are other 2 books. Even if they are for VB.NET you can find some useful code:

  1. .NET Game Programming with DirectX 9.0
  2. Beginning .NET Game Programming in VB .NET

I been working on a space sim for sometime now. At first I was using my own 3d engine with software rasterizer.

But I gave up when the time for implementing textures was due. Now I started again after sometime and now I'm using Opengl (with SDL) instead to render the 3d models.

But now I hit another brick wall.

I can't figure out how to make proper rotations. Being a space-simulator I want similar controls to a flighsim

using

glRotatef(angleX, 1.0f, 0.0f, 0.0f);
glRotatef(angleY, 0.0f, 1.0f, 0.0f);
glRotatef(angleZ, 0.0f, 0.0f, 1.0f);

or similar,
does not work properly if I rotate the model(spaceship) first 90 degrees to the left and then rotate it "up". Instead it rolls.

Here's a image that illustrate my problem.

Image Link

I tried several tricks to try and counter this but somehow I feel I missing something. It doesn't help either that simulator style rotation examples are almost impossible to find.

So I'm searching for examples, links and the theory of rotating a 3d model (like a spaceship, airplane).

Should I be using 3 vectors (left, up, forward) for orientation as I'm also going to have to calculate things like acceleration from thrusters and stuff that will change with the rotation (orientation?) and from the models perspective points in a direction like rocket-engines.

I'm not very good with math and trying to visualize a solution just give a headache

You should study 3D mathematics so that you can gain a deeper understanding of how to control rotations. If you don't know the theory it can be hard to even copy and paste correctly. Specifically texts such as 3D Math Primer(Amazon), and relevant sites like http://gamemath.com will greatly aid you in your project (and all future ones).

I understand you may not like math now, but learning the relevant arithmetic will be the best solution to your issue.

I'm looking for some material on how homogeneous coordinates, perspectives, and projections work in 3d graphics on a basic level. An approach using programming would be stellar. I've been searching around and my searches are convoluted with OpenGL, Direct3d, and material more concerned with the mathematical proofs than the actual application. Does anyone know of a place where I could find this information (online access preferred)?

I'm reading the following two books together right now to learn WPF's 3D graphics model and the underlying math at the same time. Both books are outstanding in my opinion, though it may not be what you're looking for:

3D Math Primer for Graphics and Game Development

3D Programming for Windows (this is a WPF 3d book, though the title doesn't reflect it)

You probably have to look for pre-OpenGL textbooks like Foley and van Dam's Computer Graphics: Principles and Practice in C (2nd Edition).

In particular, Ch 11 Representing Curves and Surfaces and Ch 15 Visible-Surface Determination would be relevant, but earlier material on how to draw lines and shapes would also be useful if you are truly doing everything from scratch. Something as simple as drawing a line is non-trivial if you think about it.

alt text

I truly hate asking what feels like a completely stupid question, but my lack of formal training as lead me to throw this question right out there.

I'm getting to the point in current game project where rendering the main game area/level is approaching and there is something I'm not certain about, basically with concerns to how much is actually seen vs. how much to throw into the draw commands.

This may not be what will be done, but for the sake of explaining it in an easier way I'll pose these examples. I am currently using OpenGL ES 1.1.

Say I have a character and the view is 3rd person, close to the character. I have a large level area with rooms, etc. Do I:

  1. Throw the entire level into the draw commands and assume the clipping and depth buffers do the job of trimming out what isn't seen/rendered to the screen?

  2. Break the area up, only drawing sections that could possibly be seen?

  3. Something else more efficient?

If you are making a restricted environment, like what is common in FPS games, then research Portal Occlusion.

It is a popular topic, and books such as 3D Math Primer for Graphics and Game Development and Real-Time Rendering have good overviews of the technique. Other texts can provide more detailed/thorough readings on the subject.

BSP-trees could also be useful in this type of setup.

If you are making an open, large world similar to what is in RPGs then look into using Quad/Oct-trees.

At the moment, I've been studying some OpenGL and I hope to learn as much as possible. Right now I'm writing out a shape class which I can hopefully use and derive from in other projects I choose to undertake. I've come to a realization however that there are certain elements which I need to take into consideration. One of these is the collection of mass, volume, and density - more so in relation as how to how they would apply to the geometric primitive itself.

Any axially aligned spheres or bounding boxes will likely be derived from this class, as well as primitives which will actually be rendered to the screen - both 2D and 3D alike. I was hoping to see if someone could give me some pointers on how to write a good Shape class without necessary "giving away the answer". I need a direction of some sort.

The two main resources I have at my side are Nicol Bolas' (I think that's how his name is spelled) Learning Modern Graphics Programming, and the 3D Math Primer for Graphics and Game Development book. As far as fundamentals and advanced concepts in terms of rendering and the like, these should be sufficient.

What I'm looking for at the moment though is somewhat of a guide in terms of how I could build this class. The last thing I want to do for now is just follow tutorials which involve drawing triangles on the screen from static values because I'm just one of those people who doesn't learn too well that way; I learn as a I go by implementing my own methods and relying on other sources of information at the same time.

So far, this is what I have (NOTE - none of these methods have been implemented yet, apart from ctor and inlines):

class Shape
    {
    public:
        Shape(float radius, glm::vec4 center_pos);
        virtual ~Shape(void) { }

        virtual void draw(void) = 0;
        void collide(Shape& s);
    public:
        inline void setRadius(float radius)
        {
            mRadius = radius;
            redetermineStructure();
        }

    public:
        glm::vec4 CenterPosition;
    protected:
        float mass(void);
        void redetermineStructure(void); //used to recalculate the dimensions and attributes of the primitive after a new value such as radius or position has been set.
    protected:
        float mRadius, mVolume, mDensity;
        glm::vec4 mLastPosition;
        int mHP;
    };

I'm trying to plot 3D points onto a 2D surface (I'm currently working with SDL.NET as my 'game engine'). The surface will be 800x400 pixels in size and the 3d coordinates will range from -4000 to 4000. My view will always be a top-down view and there will be no camera movement whatsoever. Could someone provide some native c#, pseudo code or an easy explanation for converting coordinates in the 3-D space to the 2-D surface?

Meanwhile Im ordering this book which people tell me it will address a lot of my math shortcomings....hopefully :)

NOTE: This is a big wall of text and I completely glaze over a lot of important stuff - but my intention here is just an overview...hopefully some of the terms/concepts here will lead you to better Googling for appropriate chunks on the web.

It helps if you walk your way through "Life as a point":

Here we are, a nice little 3-dimensional point:

var happyPoint = new Point(0, 0, 0);

And here is its buddy, defined in relation to his friend:

var friendlyPoint = new Point(1, 0, 0);

For now, let's call these two points our "model" - we'll use the term "model space" to talk about points within a single three-dimensional structure (like a house, monster, etc).

Models don't live in a vacuum, however...it's usually easier to separate the "model space" and "world space" to make things easier for model tweaking (otherwise, all your models would need to be in the same scale, have the same orientation, etc, etc, plus trying to work on them in a 3d modelling program would be friggin impossible)

So we'll define a "World Transform" for our "Model" (ok, 2 points is a lame model, but a model it remains).

What is a "World Transform"? Simply put:

  • A world transform W = T X R X S, where
  • T = translation - that is, sliding it along the X, Y, or Z axes
  • R = rotation - turning the model with respect to an axis
  • S = scaling - resizing a model (maintaining all the relative points within) along an axis

We'll take the easy out here, and just define our world transform as the Identity matrix - basically, this means we don't want it to translate, rotate, or scale:

world = [
          1 0 0 0
          0 1 0 0
          0 0 1 0
          0 0 0 1
        ];

I highly recommend you brush up on your Matrix math, especially multiplication and Vector->Matrix operations its used ALL THE FREAKING TIME in 3D graphics.

So cleverly skipping over the actual matrix multiplication, I'll just tell you that multiplying our "world transform" and our model points just ends up with our model points again (albeit in this fun new 4-dimensional vector representation, which I won't touch here).

So we've got our points, and we've absolutely located them in "space"...now what?

Well, where are we looking at it from? This leads to the concept of View Transformations or Camera Projection - basically, it's just another matrix multiplication - observe:

Say we've got a point X, at...oh, (4 2) or so:

 |
 |
 |
 |    
 |    X
 |
 ------------------------

From the perspective of the origin (0 0), X is at (4 2) - but say we put our camera off to the right?

 |
 |
 |
 |    
 |    X         >-camera
 |
 ------------------------

What is the "position" of X, relative to the camera? Probably something closer to either (0 9) or (9 0), depending on what your camera's "up" and "right" directions are. This is what View transformations are - mapping one set of 3D points to another set of 3D points such that they are "correct" from the perspective of an observer. In your case of a top-down fixed camera, your observer would be some fixed position in the sky, and all the models would be transformed accordingly.

So let's draw!

Unfortunately, our screen isn't 3D (yet), so first we need to "project" this point onto a 2D surface. Projection is...well, its basically a mapping that looks like:

(x, y, z) => (x, y)

The number of possible projections is nigh-infinite: for example, we could just shift over the X and Y coordinates by Z:

func(x, y, z) => new point2d(x + z, y + z);

Usually, you want this projection to mimic the projection the human retina does when looking at 3D scenes, however, so we bring in the concepts of a View Projection. There are a few different view projections, like Orthographic, YawPitchRoll-defined, and Perspective/FOV-defined; each of these has a couple of key bits of data you need to properly build the projection.

A Perspective/FOV based projection, for example, needs:

  • The position of your "eyeball" (i.e., the screen)
  • How far into the distance your "eyeball" is capable of focusing (the "far clipping plane")
  • Your angular field of view (i.e., hold your arms out, just at the edges of your peripheral vision)
  • The ratio of width to height for the "lens" you're looking through (typically your screen resolution)

Once you've got these numbers, you create something called a "bounding frustum", which looks a bit like a pyramid with the top lopped off:

\-----------------/
 \               /
  \             /
   \           /
    \         /
     \-------/

Or from the front:

 ___________________
|   _____________   |
|  |             |  |
|  |             |  |
|  |             |  |
|  |             |  |
|  |             |  |
|  |_____________|  |
|___________________|

I won't do the matrix calculations here, since that's all well defined elsewhere - in fact, most libraries have helper methods that'll generate the corresponding matrices for you - but here's roughly how it works:

Let's say your happy little point lies in this frustum:

\-----------------/
 \               /
  \ o<-pt       /
   \           /
    \         /
     \-------/

 ___________________
|   _____________   |
|  |             |  |
|  |             |  |
|o |             |  |
|^---- pt        |  |
|  |             |  |
|  |_____________|  |
|___________________|

Notice it's way off to the side, so far that it's out of the "near clip plane" rectangle - What would it look like if you "looked into" the smaller end of the pyramid?

Much like looking into a Prism (or a lens), the point would be "bent" into view:

 ___________________
|   _____________   |
|  |             |  |
|  |             |  |
|>>>o <- pt is   |  |
|  |    shifted  |  |
|  |             |  |
|  |_____________|  |
|___________________|

Put another way, if you had a bright light behind the frustum, where would the shadows from your points be "cast" upon the near clipping field? (the smaller rectangle) That's all projection is - a mapping of one point to another, in this case, removing the Z component and altering the X and Y accordingly in a way that "makes sense" to our eyes.