What's the purpose of magic 4 of last row in matrix 4x4 for 3D graphics?

不想你离开。 提交于 2019-12-05 07:03:27
BDL

Lets start with a bit of theory:

In general, all transformations in OpenGL are mappings between different vector spaces. This means that a transformation t takes an element from space V and maps it to it's corresponding element in space W, which can be written as

t: V ---> W

One of the simplest mappings is a linear map, which can (under some assumptions**) always be represented by a matrix. The dimension of the matrix is always given by the dimension of the vector spaces we are working in, thus a mapping from R^N to R^M will always look like this:

t: R^N ---> R^M
t(x) = A * x, A = R^(N,M)

Where A is a N times M dimensional matrix.

In OpenGL, we normally need mappings from R^3 to R^3 which means that linear mappings will always be represented by a 3x3 matrix. Using this, one can express at least rotations, scalings (and combinations of this***). But when looking at (for example) translations, we see that there is no way how they can be represented using a 3x3 matrix, so we have to extend our transformations to also support this operations.

This can be achieved by using affine mappings instead of linear ones, which are defined as

t: R^N ---> R^M
t(x) = A * x + b,  A = R^(N,M) is a linear transformation and  b = R^M

Using this we can express rotations, scalings and transformations from R^3 to R^3 by specifying a 3x3 matrix plus a 3D vector. Since this formulation is not very handy (requires a matrix and a vector, hard to combine multiple transformations), one normally stores the operation in a matrix of dimension N+1, which is called augmented matrix (or augmented vector spaces):

t: R^N ---> R^M

         -A-  b       x
t(x) = [        ] * [   ]
         -0-  1       1

As you can see, the last line of the matrix is always zero, except the rightmost element which is one. This also guarantees, that the last dimension of the result t(x) is always 1.

Why is it necessary be strictly [ 0, 0, 0, 1 ], why not just all the values be 0 or even some other value?

If we wouldn't restrict the last row to be exactly [0,0,0,1], we would not have an augmented affine mapping in R^3 anymore, but a linear mapping in R^4. Since in OpenGL R^4 is not really relevant and we want to keep translations included, the last row is fixed. Another point is, that when the last row is different, combining affine mappings by matrix multiplication would not work.

One problem left is, that we are still not able to express (perspective) projections by using affine mappings. When looking at a perspective projection matrix in OpenGL, one will notice that here the last row is not [0,0,0,1], but the theory behind this is a totally different story (if you are interested have a look here or here).

What's about the last row and why sometimes I see some calculations on it in libraries? The last one ( the homogeneous coordinate ) is modifying, so it could be not equal 1.0?

As already said, the last row is only [0,0,0,1] for affine mappings, not for projective ones. But sometimes it makes sense to apply transformations after a projection (for example moving the projected image on screen), then the last row of the matrix has to be respected. That's why most matrix libraries implement all operations in a way that allows for general matrices. The line

out[15] = a03 * x + a13 * y + a23 * z + a[15];

Will result in 1 as long as the last row (a03, a13, a23, a[15]) equals [0,0,0,1].

Since this post already got a lot longer than I thought, I'll better stop here, but if you have any further questions, just ask and I will try to add something to the answer.

Footnotes:

** Works when both spaces are finite-dimensional vector spaces and a basis is defined for both of them.

*** Combinations, since the combination of linear transformations over a finite-dimensional space is also linear, e.g., t: R^N -> R^M, u: R^M -> R^K, both linear => t(u(x)) linear

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!