How to compute inverse view matrix?

Started by
7 comments, last by AQ 19 years, 5 months ago
Hi, can anyone help me with computing precise inverse matrix of view matrix without using inverse matrix function? So having point EyePt, look at vector LookAt and up vector Up and having matrix ViewMat computed with D3DXMatrixLookAtLH function with parameters above, I want to compute inverse view matrix InvViewMat, so that ViewMat * IntViewMat = Identity matrix. But without using inverse matrix function, because inverse matrix function it's too unprecise. Thanks a lot for help.
Advertisement
How precise do you need your inverse?
I suggest you use Gauss-Jordan elimination, or a similar technique

- Tomas
Assuming the inverse matrix is orthogonal (rows contain three mutually perpendicular vectors) isn't it simply the transpose of the view matrix.
If you have a matrix M = R * T,
where R is a rotation matrix and T a translation matrix,
then your vertices are transformed from world space into view space by:

z = M * x

so

z = R * y
y = T * x

A vertex x is first translated by -EyePt, so then the camera is in the origin, then rotated so that Up points up and LookAt into z direction (correct me if I'm wrong).

R and T look like this:


R = {
{ *, *, *, 0 },
{ *, *, *, 0 },
{ *, *, *, 0 },
{ 0, 0, 0, 1 }
}

T = {
{ 1, 0, 0, a },
{ 0, 1, 0, b },
{ 0, 0, 1, c },
{ 0, 0, 0, 1 }
}

where * are numbers.


Since a rotation matrix is orthogonal, R^-1 = R^t (transpose).
And T^-1 can be obtained by replacing a,b and c by its negative values.


Then you can easily calculate M^-1:

M^-1 = T^-1 * R^-1



How precise do you need your inverse?
As much as D3DXMATRIX can be of course. :-)

What D3DXMatrixLookAtLH Function does is:

zaxis = normal(At - Eye)
xaxis = normal(cross(Up, zaxis))
yaxis = cross(zaxis, xaxis)

xaxis.x yaxis.x zaxis.x 0
xaxis.y yaxis.y zaxis.y 0
xaxis.z yaxis.z zaxis.z 0
-dot(xaxis, eye) -dot(yaxis, eye) -dot(zaxis, eye) 1

And I'm looking for recipe in similar way of how to compute
inverse view matrix to matrix above?

Quote:Original post by Filousov
How precise do you need your inverse?
As much as D3DXMATRIX can be of course. :-)

What D3DXMatrixLookAtLH Function does is:

zaxis = normal(At - Eye)
xaxis = normal(cross(Up, zaxis))
yaxis = cross(zaxis, xaxis)

xaxis.x yaxis.x zaxis.x 0
xaxis.y yaxis.y zaxis.y 0
xaxis.z yaxis.z zaxis.z 0
-dot(xaxis, eye) -dot(yaxis, eye) -dot(zaxis, eye) 1

And I'm looking for recipe in similar way of how to compute
inverse view matrix to matrix above?

It should be:
zaxis = normal(At - Eye)xaxis = normal(cross(Up, zaxis))yaxis = cross(zaxis, xaxis) xaxis.x           xaxis.y           xaxis.z          0 yaxis.x           yaxis.y           yaxis.z          0 zaxis.x           zaxis.y           zaxis.z          0 eye.x             eye.y             eye.z            1


edit: Do you finding the inverse from an existing matrix created by D3DXMatrixLookAtLH? If so ignore that.

To do it from an existing matrix:

m._41 = -(x.x * y.x + x.y * y.y + x.z * y.z)
-m._41 - (x.y * y.y + x.z * y.z) = x.x * y.x
(-m._41 - (x.y * y.y + x.z * y.z)) / x.x = y.x

m._42 = -(x.x * y.x + x.y * y.y + x.z * y.z)
-m._42 - (x.x * y.x + x.z * y.z) = x.y * y.y
(-m._42 - (x.x * y.x + x.z * y.z)) / x.y = y.y

m._43 = -(x.x * y.x + x.y * y.y + x.z * y.z)
-m._43 - (x.x * y.x + x.y * y.y) = x.z * y.z
(-m._43 - (x.x * y.x + x.y * y.y)) / x.z = y.z
y.x = (-m._41 - (x.y * y.y + x.z * y.z)) / x.xy.y = (-m._42 - (x.x * y.x + x.z * y.z)) / x.yy.z = (-m._43 - (x.x * y.x + x.y * y.y)) / x.z

to find y, it is a very unfun system of equations of the above but the rotation part looks like this:
xaxis = < m._11, m._12, m._13 >yaxis = < m._21, m._22, m._23 >zaxis = < m._31, m._32, m._33 >xaxis.x xaxis.y xaxis.zyaxis.x yaxis.y yaxis.zzaxis.x zaxis.y zaxis.zy.x     y.y     y.z

If you solve that system and plug it into the matrix like above, it should work.

Another option is to write your own matrix inversion function using doubles to do the calculation, however, it would certainly be slower than D3DX's matrix inverse function.

[Edited by - Kibble on December 12, 2004 3:08:22 PM]
Oh, yes.
Thank you for help
Given a final matrix (the ones obtained from the lookAt function), and assuming you had no non-uniform scaling done on the camera, matrix, then upper 3x3 represent a rotation only matrix and the 4th row = position.

Irresective of how you arrived at this matrix, it can NOW be written as the product of a translation matrix and a rotation matrix, like this



M = R * T

M = the matrix that lookAt finction gave you .. and R = upper 3x3 of M and
[0 0 0 1] as its 4th row (which represents the position)

And T = identity matrix except that 4th row is the 4th row from M

Thus R is now a rotation-only matrix and T is a translation only matrix.

(multiply these two and confirm that you do get back the M)

given this, now

MInv = INV (R * T)
= TInv * RInv


(this is from the matrix multiplication rule that AB inverse = Binv Ainv)

Now T is simply a translation-only matrix therefore its inverse is obtained by simply negating the its x y and z components.

M is a rotation only matrix and for them the property holds that inverse of a rotation only matrix is the same as its transpose. (read some matrix algebra book to see why, but for our purposes this works).

Thus to sumamries, to compute the inverse provided you your matrix has no non-uniform scaling in it, can be obtained by

1. compute the negative of the 4th row. Create an identity matrix and change its 4th row with these numbers. Call it Tinv.

2. Copy the original matrix and set its 4th row to [0 0 0 1], thereby setting its position information to zero. This is now a rotation only matrix.
3. Transpose this matrix. This is also now the inverse of the rotation-only matrix. Call it MInv.

4. Compute the inverse of the original matrix by computing Tinv * Minv.

Count your blessings before you count your problems.www.wiu.edu/users/muaiq

This topic is closed to new replies.

Advertisement