Matrix stuff

Hello,
Because i’m now into OpenGL shading language programming, I thought it would be a good idea to figure out what actually matrices are.
I now know how simple translation and scaling works using a identity matrix.
But my GLSL book also talks about an inverse matrix, transpose matrix and inversetranspose matrix.
I’ve figured(thanks to wikipedia :-)) that the transpose of a matrix is that rows are turned into columns(or the other way round).
And i’ve also found out that the inverse of a matrix is mymatr^(-1) (equals to 1/myattr ?), although I not yet understand how they calculate the inverse of a matrix.
But what I really want to know is, what are the use of those matrices?
Why(and when) do I need them?
I hope y’all can help me a little with this math stuff.
Thanks in advance,
Hylke

Hi,

first, the inverse matrix of a matrix A is denoted A^-1 however, it does not mean 1/A. A^-1 is the matrix such that A*A^-1 = I, where I is the identity matrix. As far as calculating inverse matrices, consult a linear algebra book to learn how to do this.

The use of an inverse matrix is to ‘undo’ a transformation. For example in a vertex shader you multply a vertex’s world postion by the modelview matrix to transform into clip space, however, at some point you may need a vertex position back in world space, so you would multiply the vertex by the inverse modelview matrix to go back to world space (this was a contrived example so it might seem irrational).

Under some conditions the transpose of a matrix can be the matrix’s inverse.

Hello brtnrdr,
Thank you for your reply. Now that I know this the formula also makes sense.
But what I do not fully understand now, is why I would want to use the transpose matrix.
I hope you can also help me with that.
Thanks in advance,
Hylke

The inverse transpose is needed to transform the normal. It’s just simple mathematics:

In lighting calculations, you use this term:
n . p (that’s a dot product)

n is the normal, and p is some position (usually light relative to the vertex)

If you see the column vectors n and p as 4x1 matrices, the dot product can be written as matrix product:

nT * p (nT is n transposed, a 1x4 matrix)

Thats a 1x4 matrix * a 4x1 matrix, the result is a 1x1 matrix (also known as number :stuck_out_tongue: ).

Now we have the problem that we have the position in view space, that is:

M * p (that’s still a 4x1 matrix)

M is the modelview matrix, a 4x4 matrix. We are looking for a matrix to multiply with the normal, so the dot product stays the same:

n . p == (Nn) . (Mp)

In matrix form:

(Nn)T * (Mp)

The matrix we are looking for is the inverse transposed modelview matrix (M^-1)T, because:

((M^-1)T * n) . (M * p) ==
((M^-1)T * n)T * (Mp) ==
(nT * (M^-1)TT) * (M
p) == // because (A*B)T == BT * AT
nT * (M^-1 * M) * p == // because ATT == A
nT * p ==
n . p

Ok, I think I understand it, sort of. But I still have a question:

Originally posted by Overmind:
The matrix we are looking for is the inverse transposed modelview matrix (M^-1)T, because:

((M^-1)T * n) . (M * p) ==
((M^-1)T * n)T * (Mp) ==
(nT * (M^-1)TT) * (M
p) == // because (A*B)T == BT * AT
nT * (M^-1 * M) * p == // because ATT == A
nT * p ==
n . p
I think I understand why to use the inverse transpose matrix:
Transpose: So that you can use a matrix style multiplication.
Inverse: Because normal is not in viewspace.
But I don’t understand what those calculating things have todo with it.

Why don’t I learn such things in school? :slight_smile:

No, I think you didn’t understand correctly :wink:

The first line of the equations and the last line are equal. That’s the whole point of it.

You use the inverse transpose modelview matrix because these two lines have to be equal. If you’d use another matrix, they would not be equal (easily shown by repeating my calculations with some other matrix).

If you transform the whole scene (light position + object), the lighting should not change. And the dot product in the first line of my equations is a part of the lighting calculations.

But if those things are equal, then what’s the point of using the matrices?
For example: 3x*(1/3) is simply x, isn’t that the same thing you’re big ass calculation boils down to?

The equations that Overmind showed you are not what’s happening inside OpenGL. OpenGL simply multiplies each vertex position with the modelview matrix and each vertex normal with the inverse transpose of the modelview matrix.

What Overmind showed you, was the /proof/, that, when transforming a surface by matrix M, you have to transform the surface normals by (M^-1)T to keep the relation between normals and surface intact.

Yes, what I showed is not something OpenGL will calculate, it’s just to show why we need to use the inverse transpose matrix. I wouldn’t go as far as calling it a proof…

3x*(1/3) is simply x, isn’t that the same thing you’re big ass calculation boils down to?
Yes. Assume you don’t know x, you only know 3x, but you need to calculate xy. So you just calculate 3x(1/3)*y.

With the matrices it’s the same. You only have the light position in view coordinates, so the light-vertex vector will be in view coordinates, too… That’s (M * p) in my calculations, you don’t know p.

Ok, I think I get it now.
But I have one final question about the formula for creating an inverse (4x4)matrix(in C++).
According to wikipedia it’s:
A^(-1) = 1/det(a)*adj(a)
det = Determinant function
adj = Adjugate function
So my first step was finding out how the determinant function worked.
The formula for that was:

So I now have the following code for the determinant function:

	for(unsigned int i = 0;i < 4;i++)
	{
		for(unsigned int j = 0;j < 4;j++)
		{
			float matrixsum = 0.0;
			for(unsigned int k = 0;k < 4;k++)
			{
				for(unsigned int l = 0;l < 4;l++)
				{
					if(k == i &#0124;&#0124; l == j)
						continue;
					matrixsum += mat.data[i][j];
				}
			}
			returnvalue.data[i][j] = mat.data[i][j]*pow(-1, i+j)*matrixsum;
		}
	}

And i’ve also found the formula for a adjugate matrix:

So the total formula would look like this:

                 (-1)^(i+j)*Mi,j
INVERSE MATRIXi,j = ------------------
                 Ai,j*(-1)^(i+j)*Mi,j

which equals to:

                           1
INVERSE MATRIXi,j = ------------------
                         Ai,j

But that’s not correct, because if you translate a mtrix, the x component of the translation shouldn’t be 1/A[sub]ij[/sub] but it should be -A[sub]ij[/sub] instead.
So I’m hoping somebody can help me with this stuff.
Thanks in advance,
Hylke

About the inverse matrix calculations:
A = the matrix to be inversed
M = the minor of the matrix A

I think you dropped a sum symbol somewhere in your calculation. Also you forgot a transposition.

The determinant of a matrix is a single number. The formula you posted is correct, but the code is not. You should build the sum over j. The i in the formula is not a loop variable, it can be chosen arbitrarily (for example 0). You could also sum over i with an arbitrary j, doesn’t matter.

In your code you calculate Mi,j as just a sum of matrix elements. It really should be recursively the determinant of the submatrix with row i and column j deleted.

So the total formula looks like this:

                         (-1)^(i+j)*Mj,i
INVERSE MATRIXi,j = --------------------------
                   SUM(k=0..n) A0,k*(-1)^k*M0,k

Mi,j is the minor of matrix A, which is the determinant of the matrix A with row i and column j deleted.

This can not be further simplified, except for the fact that the sum needs only be calculated once.

Of course, for a fixed matrix dimension you can unroll the loops and the recursion to get a single formula, that’s more efficient than actually coding everything.

See here for a lot of matrix code, both for 4x4 matrices and for the general case:
http://www.euclideanspace.com/maths/algebra/matrix/code/index.htm

Sorry for my late reply.
But thank you very much for your replies.
Hylke