Basic Matrix question

E55b318b3756abbaf127688408a556ca
0
Unfadable 101 Sep 27, 2005 at 21:55

Sorry if this question seems simple, but I’m finding all kinds of conflicting info on the net.

My understanding of D3D matrices are that the basis vectors are in the columns of the matrix and for OpenGL the basis vectors go into rows of the matrices.

And also, D3D matrices are stored in row-major format meaning that row elements are next to each other in memory. Row-major doesn’t suggest anything about the basis vectors.

Right-handed vs left-handedness is represented in a matrix by the direction it rotates points/vectors (counter-clockwise vs clockwise).

14 Replies

Please log in or register to post a reply.

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Sep 28, 2005 at 04:48

In both OpenGL and D3D matrices, the basis vectors go into the columns of the matrix.

However, OpenGL expects matrices in column-major order, while D3D expects them in row-major order (and, as far as I know, most programmers’ matrix classes are usually in row-major order). Thus, row-major matrices must be transposed to send them to OpenGL.

A 3x3 matrix is not right-handed or left-handed in itself, but if its determinant is > 0 then it is orientation-preserving, meaning it takes a right-handed basis to a right-handed one, and the same for left-handed bases. If the determinant is < 0, it is orientation-reversing, so it takes a right-handed basis to a left-handed one (and vice versa).

E55b318b3756abbaf127688408a556ca
0
Unfadable 101 Sep 28, 2005 at 12:56

Hey thanks for the reply. I’m still a condused:.

In an earlier post about extracting view direction you said
“If you are using OpenGL, the viewing direction is the negative of the 3rd row of the viewing matrix. (This is assuming your viewing transform uses only translations and rotations, not anything weird…)”

How come the view direction is not the 3rd column? Isn’t the view direction just the z basis vector?

Btw, I don’t know anything about OpenGL. I believe the DirectX LookAt function puts the view direction into the column.

340bf64ac6abda6e40f7e860279823cb
0
_oisyn 101 Sep 28, 2005 at 14:10

@Reedbeta

In both OpenGL and D3D matrices, the basis vectors go into the columns of the matrix. However, OpenGL expects matrices in column-major order, while D3D expects them in row-major order (and, as far as I know, most programmers’ matrix classes are usually in row-major order). Thus, row-major matrices must be transposed to send them to OpenGL.

This is not correct. D3D uses row-vectors, which basically means that a 4d vector is a 1 (row) x 4 (colums) matrix. In order to transform a 1x4 vector V with a 4x4 matrix M, you need to do V*M. Also, a transformation of M1 followed by a transformation of M2 yields the matrix M1 * M2. Base vectors in the matrix are ~~columns~~ rows

OpenGL uses colum-vectors, e.g. a vector is a 4x1 matrix. Tranformation is done by doing M * V, and accumulated transformations are done with M2 * M1. Base vectors in the matrix are ~~rows~~ columns.

Therefore, a d3d matrix is transposed with respect to an OpenGL matrix in the mathematical sense. BUT, since d3d stores it’s matrices row-major, while OpenGL stores it column-major, both types of matrices have the same memory layout (the reason for OpenGL using a column-major order is that the basevectors are therefore stored sequentially in memory)

.edit: nasty typo’s fixed

4e70f904a74bd2aa8773733b25b77d41
0
SigKILL 101 Sep 28, 2005 at 14:16

If ‘basis’ vectors means the basis for the 3x3 rotational component of the matrix, then in D3D the basis is put in the rows, and in OGL it is put in the columns. This can easily be checked since transforming a vertex v by a matrix A in D3D means multiplying the vector from the left (i.e. v*A), while in OGL you multiply from the right (i.e. A*v). Since ogl is column major, and d3d is row major this leads in practice to D3D and OGL matrices very often to have the same layout in memory (you should probably be careful when working with projection matrices etc).

To get the viewing direction from an OGL matrix use the inverse of the third column (not row)..

Edit: Yeah, D3D row vectors, OGL column vectors..

-si

E55b318b3756abbaf127688408a556ca
0
Unfadable 101 Sep 28, 2005 at 14:56

Hey guys,

I’m almost understanding, plz bear w/me. And hopefully you guys understand why I’m confused :P

By basis vectors, I mean up, right, and view orthonormal vectors. Is there another meaning?

.oisyn and SigKILL thanks for the replies. From what I understand .oisyn is saying d3d base vectors are in columns and SigKill is saying d3d base vectors are in the rows. Did I misinterpret this?

  • Is this correct?
    D3D_________
    R.x U.x V.x 0
    R.y U.y V.y 0
    R.z U.z V.z 0
    T.x T.y T.z 1

OpenGL________
R.x R.y R.z T.x
U.x U.y U.z T.y
V.x V.y V.z T.z
0 0 0 1

4e70f904a74bd2aa8773733b25b77d41
0
SigKILL 101 Sep 28, 2005 at 15:07

Almost:

D3D_____
R.X R.Y R.Z 0
U.X U.Y U.Z 0
V.X V.Y V.Z 0
T.x T.y T.z 1

OpenGL________
R.x U.x V.x T.x
R.y U.y V.y T.y
R.z U.z V.z T.z
0 0 0 1

Where R,U and V are the basis vectors, and T is the translation…
It is so easy to check this: having v in model-space you should get something in world-space by doing v*A in D3D and A*v in OGL.

-si

E55b318b3756abbaf127688408a556ca
0
Unfadable 101 Sep 28, 2005 at 15:25

I found this implementation of D3DXMatrixLookAtLH, where ZAxis is the vector from look at point to eye, xAxis is ZAxis.Cross(upVector), etc

pOut->_11 = XAxis.x;
pOut->_21 = XAxis.y;
pOut->_31 = XAxis.z;
pOut->_41 = -D3DXVec3Dot(&XAxis, pEye);

pOut->_12 = YAxis.x;
pOut->_22 = YAxis.y;
pOut->_32 = YAxis.z;
pOut->_42 = -D3DXVec3Dot(&YAxis, pEye);

pOut->_13 = ZAxis.x;
pOut->_23 = ZAxis.y;
pOut->_33 = ZAxis.z;
pOut->_43 = -D3DXVec3Dot(&ZAxis, pEye);

The ZAxis is placed into the columns. So this is transposed to form an inverse rotation?

A8433b04cb41dd57113740b779f61acb
0
Reedbeta 167 Sep 28, 2005 at 16:07

The camera view direction is the (negative of) the third row of the 3x3 modelview matrix, not the third column. This is because the modelview matrix takes world space to eye space; therefore, its inverse (= transpose of the 3x3 part, if only rotations/translations are used) takes eye space to world space, and so the world space basis vector can be extracted from the third column of this matrix. It’s negative because in OpenGL, the eye looks down the -Z axis in eye space.

4e70f904a74bd2aa8773733b25b77d41
0
SigKILL 101 Sep 28, 2005 at 16:37

“The camera view direction is the (negative of) the third row of the 3x3 modelview matrix, not the third column.”

Urgh, my bad. I’m just really tired today. It should of course be the third column of the inverse. This is of course the third row when only rotations and translations are used…

-Si

P.S. I’m really looking forward to becoming a member instead of a “new member”. I joined over a year ago…

4e70f904a74bd2aa8773733b25b77d41
0
SigKILL 101 Sep 28, 2005 at 16:41

@.oisyn

This is not correct. D3D uses row-vectors, which basically means that a 4d vector is a 1 (row) x 4 (colums) matrix. In order to transform a 1x4 vector V with a 4x4 matrix M, you need to do V*M. Also, a transformation of M1 followed by a transformation of M2 yields the matrix M1 * M2. Base vectors in the matrix are columns OpenGL uses colum-vectors, e.g. a vector is a 4x1 matrix. Tranformation is done by doing M * V, and accumulated transformations are done with M2 * M1. Base vectors in the matrix are rows.

There might be confusion because we seem to define basis vectors differently.I’m thinking of a given vector in some “model space”, the basis is the “model space” basis given relative to the “world space”, and the transformation goes from “model space” to “world space”. It might seem that you’re thinking the other way around. Your way makes things look ugly when scaling etc. is involved IMO…

-Si

P.S. Member yet?

E55b318b3756abbaf127688408a556ca
0
Unfadable 101 Sep 28, 2005 at 17:15

Cool, well I think I understand this now. Thanks everyone for their input.

But please, anyone, feel free to add more to the subject if you’d like.

Unfadable

340bf64ac6abda6e40f7e860279823cb
0
_oisyn 101 Sep 28, 2005 at 18:46

@Unfadable

Hey guys,
.oisyn and SigKILL thanks for the replies. From what I understand .oisyn is saying d3d base vectors are in columns and SigKill is saying d3d base vectors are in the rows. Did I misinterpret this?

No, you interpreted it correctly, I flipped the meaning of column and row in my head when writing down the base vector orientations. SigKILL is correct, D3D has it’s base vectors in the rows, OGL in the columns (otherwise my post wouldn’t be consistent as I claim that OGL had chosen for row-major matrices because of the contiguous memory layout for the base vectors, which wouldn’t be the case if the base vectors were in the rows :))

7543b5c50738e23b200e69fe697ea85a
0
NomadRock 101 Sep 28, 2005 at 19:36

SigKill, your new member status is totally based on your post count. To date you have posted 20 times. Being more active across the board as you are in this thread will ensure you very quickly rise in rank. Obviously spamming is discouraged though =p

4e70f904a74bd2aa8773733b25b77d41
0
SigKILL 101 Sep 29, 2005 at 11:01

I was hoping I would become a ‘member’ when I reached 20 posts.. I was wrong..

-si