XNA requires 3 matrices to be set before 3D geometry can be rendered. These matrices are used to transform the 3D geometry from its initial definition in model space e.g. your art package into the final image drawn on the screen in 2D screen space.
The steps the geometry goes through are:
So the three matrix are:
XNA provides many functions to help you create these matrices. Some are described below along with common settings and examples.
Different graphic libraries vary in the axis system they use. For example native Direct3D uses a left handed system where X is right, Y up and Z in to the screen while XNA and OpenGL use a right handed system where X is right, Y is up and Z is out of the screen. To convert between the two systems you can invert any one of the axis (but only one). I normally invert Z but inverting either of the others is also valid. Note that you cannot convert from one of these co-ordinate systems to another using rotations.
Note: these are the two most commonly used co-ordinate systems but there are others e.g. 3DS Max has Z up Y into the screen and X right. To convert from a right handed system to the 3DS Max system you swap -Z and Y co-ordinates.
XNA provides a matrix type called Matrix. This is a class that contains 4 by 4 elements for the matrix values. You can declare one simply:
Matrix worldMatrix=Matrix.Identity;
This creates a variable of type Matrix, calls it worldMatrix and sets it to the identity matrix. The identity matrix is one which when multiplied by another results in the other i.e. no change. So Identity * MatrixA = MatrixA. It is therefore common to initialise matrix to identity.
Your world matrix is used to transform from model space into world space. You use it to take your 3D models and position, scale and rotate them into the game world. Model space is the space you created your model in e.g. in an art package where 0,0,0 is normally the centre of the object and vertex positions are defined relative to this. You want to place this object into your game world so you need to translate, rotate and scale it into world space. There are a number of helper functions that you can use to create this matrix:
Matrix.CreateTranslation(translationVector);
This function takes a Vector3 with the x, y and z position of the object in the world. It then returns a matrix that, when applied to the model geometry, will transform it into world space correctly. So if you want your object to be located at 10,0,50 you might write:
Matrix worldTranslation=Matrix.CreateTranslation(new Vector3(10,0,50));
After this call the matrix is filled with the values required to carry out this transform.
Matrix.CreateRotationX(angle)
Matrix.CreateRotationY(angle)
Matrix.CreateRotationZ(angle)
These three functions allow you to set up your matrix to rotate the object around one of the axis. You use the function you require and specify the rotation angle in radians. E.g. to rotate a object 180 degrees around the Y axis we could write:
Matrix worldRotation=Matrix.CreateRotationY(MathHelper.Pi)
MathHelper.Pi is a provided value for PI, PI is 180 degrees in radians. The Math class also provides PI but the MathHelper one returns a float which is more convenient here. See the note at the end of this section about converting Radians and Degrees
The final thing you can do with your world matrix is specify a scale. So you could make your object twice as big by scaling it with a value of 2
Matrix worldSclae=Matrix.CreateScale(2.0f);
Not that the above scaled the model in all axis by 2. Other overloads exist to allow you to scale it differently in the different axis.
Using the above functions you can position, rotate and scale your 3D object into your world. There is one important thing to note however and that is that you must do these matrix operations in a certain order since matrix multiplication is not cumulative. In XNA you must combine your matrix in SRT order (scale * rotation * translation).
Sometimes you will heard these axis rotations referred to by yaw, pitch and roll. Rotation around the y axis is called yaw, around the x axis is called pitch and around the z axis is roll.
Therefore if you want to position your entity at position position with scale scale and rotation rotations you could write:
Matrix modelWorldMatrix = Matrix.CreateScale(scale) * Matrix.CreateRotationX(rotations.X) *
Matrix.CreateRotationY(rotations.Y) *
Matrix.CreateRotationZ(rotations.Z) *
Matrix.CreateTranslation(position);
The above multiplies all three rotations separately to show the working but you could do them in one using
Matrix.CreateFromYawPitchRoll(rotations.y,rotations.x,rotations.z);
Do remember to always multiply the matrix in Scale, Rotation, Translation (SRT) order!
The view matrix transforms from world space into view space. It allows you to specify a position in the world where the view will be seen from. This needs to be set whenever the camera position and/or direction is changed.
Camera control is in a separate topic (see XNA Camera), here I will just describe a simple method for creating the view matrix. The function builds a view matrix from some inputs:
Matrix Matrix.CreateLookAt(Vector3 cameraPosition, Vector3 cameraTarget, Vector3 cameraUpVector)
An example of creating and setting a view matrix to represent the camera positioned at 0,3,5 looking at 0,0,0 and upright (0,1,0):
Matrix viewMatrix=Matrix.CreateLookAt(new Vector3(0,3,5), new Vector3(0,0,0), new Vector3(0,1,0));
XNA usefully provides a zero vector and up vector so we could also write the above as:
Matrix viewMatrix=Matrix.CreateLookAt(new Vector3(0,3,5),Vector3.Zero,Vector3.Up);
The projection matrix specifies how our 3D view space data is transformed onto our 2D screen. This is where we can specify the perspective to use. We use the following function that builds a projection matrix for us:
Matrix.CreatePerspectiveFieldOfView(float fieldOfView, float aspectRatio, float nearPlaneDistance, float farPlaneDistance)
Note: this matrix is normally only set once in a game, at the start unless you are doing any fancy effects or techniques like rendering to a texture.
An example of creating and setting this matrix might be:
float aspect = (float)screenWidth / (float)screenHeight;
Matrix projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspect, 1, 100);
Note the use of the MathHelper class. It provides lots of useful constants like PiOver4, PiOver2 and useful functionality like clamp.
PI radians is 180 degrees. 2 PI is 360 degrees. Often it is easier to think in terms of degrees rather than radians. To convert between the two you can use the following MathHelper functions
MathHelper.ToDegree(radians)
MathHelper.ToRadians(degrees)
There are three matrix used by XNA to transform your 3D models into the final 2D image you see on the screen. They are the World Matrix, the View Matrix and the Projection Matrix. Note: If you are coming from a OpenGL background OpenGL combines the first two together.
You create your 3D model in Object Space. You apply a world matrix to transform from object space into world space. To take the camera into account you apply a view matrix to transform from world space into view space and finally you apply a projection matrix to transform from view space into screen space.
XNA provides a number of functions that allow you to easily create your matrix.
The world matrix needs to be calculated to position every entity you render
The view matrix is calculated each time the camera changes position or orientation
The projection matrix is normally calculated just once at the start of your game