Wednesday, October 19, 2011

DirectX Matrices Related to Viewing

I promised a while back to write a post that related the theory in the lecture that I did a while back on viewing/cameras/projection in DirectX, but alas I haven't had the chance until now. Though it's perhaps a bit late, hopefully this can serve as another point of view for understanding things, or act as a reference.

The Toymaker website I mentioned in an earlier post has a good page on the various matrices you need in Direct3D to go from your model to the screen.  Let's have a look at the descriptions there and see how it relates to the terminology and concepts from my lecture.

Note: DirectX assumes a horizontal/row vector that is multiplied on the left hand side of the transformation matrices.  This means that the transformations are applied from left to right.  In linear algebra class and in my notes, a vertical/column vector is multiplied on the right hand side so that transformations are actually applied right to left.  I'm not going to switch things around from my lecture here, so keep this discrepancy in mind when looking at the Toymaker site in more detail.

Toymaker lists the following three matrices used to transform your game content from 3D model space to 2D screen space:
  1. World Matrix - Transforms 3D data from Model Space into World Space. You need to set this before rendering every entity in your world.
  2. View Matrix - Transforms from World Space into View Space. You need to set this each time your camera changes position
  3. Projection Matrix - Transforms from View Space into Screen Space. You normally set this just once during initialization.
The projection matrix mentioned here is like MoMp from my slides (i.e. the combination of the orthographic projection, which included the windowing transform, and the projection transform that squished the view frustum into a rectangular prism).

The view matrix here is the same as the view matrix Mv in my slides, which essentially did a coordinate transform so the model points in world coordinates would instead become relative to the camera's coordinate system.

The world matrix isn't something I talked about explicitly in the slides.  If you look at the orthographic viewing volume or the view frustum, you can imagine that the model points inside are going to be in the coordinate system of the world or camera (depending which stage you are looking at).  Of course, if our models are defined according to their own coordinate systems, then their points would first have to be transformed to be relative to the world coordinate system.

Toymaker goes on to show the nice helper functions that DirectX has to help you set up these three matrices.  You don't even have to know how these matrices look.

For the view matrix, you can use the same entities we defined in the slides to define where the camera is.  Then DirectX will construct the viewing matrix for you.  As described on Toymaker:
D3DXMatrixLookAtLH(D3DXMATRIX *out, CONST D3DXVECTOR3 *eye, CONST D3DXVECTOR3 *at, CONST D3DXVECTOR3 *up );
  • out - this is where we pass in the address of the matrix we want filling
  • eye - the world position of the eye point
  • at - the position in the world we are looking at
  • up - defines which way is up. This is needed because if you are positioned somewhere in the world looking in a certain direction you could be upright or standing on your head and in each case the position and direction would still be the same. So to determine which way up we are we need to provide it here
So the 'eye' here is the eye position/camera center e in the slides, 'at' here is the gaze direction g in the slides, and 'up' here is the view-up vector t in the slides.

Notice that the projection matrix is defined on Toymaker a bit differently than we define it (in addition to the fact that the DirectX projection matrix takes you from the world to the screen in one fell swoop).  While we talked about the view frustum as a set of planes, they use the field of view, aspect, and near and far planes instead.  Either way is fine because there is enough information to move from one representation to the other - for instance, the field of view can be determined at the angle between the lines from the origin to the edges of the frustum's side planes.

That should basically cover it.  You can take a look at the Toymaker page on cameras as well to see some methods they use to define the view matrix.  I encourage you to try to relate what you see there to what's in the slides to get a good feel for how well you understand the concepts.

No comments:

Post a Comment