理解OpenGL矩阵

21

我开始学习3D渲染,进展不错。我已经学会了很多关于矩阵及其一般操作的知识。

但有一件事情我仍然不太明白,那就是OpenGL对矩阵的使用。我经常看到像这样的东西:

x y z n
-------
1 0 0 0
0 1 0 0
0 0 1 0
0 0 0 1

据我所知,它是一个规范化(无量纲)的4维列主矩阵。同时,这个特定的矩阵被称为“单位矩阵”。

一些问题:

  • 第N维是什么?
  • 如何以及何时应用它们?

我最大的疑惑来自于OpenGL如何利用这种数据。


请查看书籍《游戏和交互应用的基本数学》http://www.essentialmath.com/book.htm。 - Mr. Berna
2
一个标准化向量并不是“没有大小”。标准化向量的长度/大小为1。 - alesplin
谢谢!我想我在理解上有些过度了。至少我走在了正确的轨道上。;) - Alexander Trauzzi
相关问题:http://gamedev.stackexchange.com/questions/72044/why-do-we-use-4x4-matrices-to-transform-things-in-3d - Ciro Santilli OurBigBook.com
相关问答:理解4x4齐次变换矩阵 - Spektre
2个回答

68
在大多数三维图形中,一个点由一个四元向量(x,y,z,w)表示,其中w = 1。应用于点的常规操作包括平移,缩放,旋转,反射,扭曲和这些操作的组合。
这些变换可以由称为“矩阵”的数学对象表示。矩阵对向量的应用如下:
[ a b c tx ] [ x ]   [ a*x + b*y + c*z + tx*w ]
| d e f ty | | y | = | d*x + e*y + f*z + ty*w |
| g h i tz | | z |   | g*x + h*y + i*z + tz*w |
[ p q r s  ] [ w ]   [ p*x + q*y + r*z +  s*w ]

例如,缩放被表示为:
[ 2 . . . ] [ x ]   [ 2x ]
| . 2 . . | | y | = | 2y |
| . . 2 . | | z |   | 2z |
[ . . . 1 ] [ 1 ]   [ 1  ]

和翻译作为

[ 1 . . dx ] [ x ]   [ x + dx ]
| . 1 . dy | | y | = | y + dy |
| . . 1 dz | | z |   | z + dz |
[ . . . 1  ] [ 1 ]   [   1    ]

第四个组件的原因之一是使翻译可以用矩阵表示。

使用矩阵的优点在于,通过矩阵乘法可以将多个变换组合成一个。

现在,如果目的只是为了将翻译放在桌面上,那么我会使用 (x、y、z、1) 而不是 (x、y、z、w),并始终将矩阵的最后一行设置为 [0 0 0 1],就像通常用于二维图形一样。实际上,这个四分量向量将通过以下公式映射回正常的三分量向量:

[ x(3D) ]   [ x / w ]
| y(3D) ] = | y / w |
[ z(3D) ]   [ z / w ]

这被称为齐次坐标。允许这样做可以使用矩阵表示透视投影,这可以再次与所有其他变换组合使用。
例如,由于远离观察者的物体在屏幕上应该更小,因此我们使用公式将3D坐标转换为2D坐标。
x(2D) = x(3D) / (10 * z(3D))
y(2D) = y(3D) / (10 * z(3D))

现在,如果我们应用投影矩阵。
[ 1 . .  . ] [ x ]   [  x   ]
| . 1 .  . | | y | = |  y   |
| . . 1  . | | z |   |  z   |
[ . . 10 . ] [ 1 ]   [ 10*z ]

如果是真实的三维坐标,那么就会变成这样。
x(3D) := x/w = x/10z
y(3D) := y/w = y/10z
z(3D) := z/w = 0.1

所以我们只需要去掉z坐标来投射到二维平面。


3
抱歉,我不太明白你的例子,希望能理解。对不起。 - Alexander Trauzzi
1
@ Omega 这本OpenGL红宝书的这一章可能会有所帮助 http://www.glprogramming.com/red/appendixf.html#name1 - Swiss
@Omega 或许基础知识也很有用 [http://en.wikipedia.org/wiki/Matrix_multiplication]。 - Luca
一点一点地,我正在逐渐理解。请记住,我还需要理解OpenGL的实现。 我想我明白了,OpenGL使用矩阵作为基本数据类型来定义各种变换。API中的许多函数似乎就是用来生成这些矩阵的。不管怎样,我肯定已经加强了对可以在这些矩阵上执行的各种算术运算的理解。 - Alexander Trauzzi

3
可能会对您有所帮助的简短答案是,“nth”维度并不代表任何可视化的数量。它作为实用工具添加到矩阵乘法中,以实现平移和透视投影。直观的3x3矩阵无法完成这些任务。
一个表示空间中一点的3D值,总是在第四个值上加上1才能让这个技巧起作用。而一个表示方向的3D值(即法线,如果您熟悉该术语),则在第四个位置上加0。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接