1. 程式人生 > >gluLookAt矩陣推導

gluLookAt矩陣推導

最近需要自己手動算camera view矩陣,但是推導的結果跟OpenGL官方文件不一樣,又因為我的瀏覽器沒法完美看MathML,所以我一直以為OpenGL的官方文件http://www.opengl.org/sdk/docs/man/xhtml/gluLookAt.xml錯了,今天才發現原來最終結果是一樣的,困擾了我好久的一個問題終於解決了。

這裡我準備從基變換的角度來推導這個矩陣。首先考慮2D的簡單情況。現在的問題是,將空間從規範基(canonical basis)轉換到照相機的基。

規範基是{(1, 0)^T, (0, 1)^T}, 照相機的基是{u, v},對於任意一個向量(s, t)^T,它的座標在規範基下是(s, t)^T,也就是

(s, t)^T = s * (1, 0)^T + t * (0, 1)^T

如果可以將(0, 1)和(1, 0)用{u, v}表示,那麼我們也可以求得(s, t)^T在另一組基下的座標。

假設

(1, 0)^T = a * u + b * v

(0, 1)^T = c * u + d * v

那麼帶入上面的式子

(s, t)^T = s * (au + bv) + t * (cu + dv) = (as + ct) * u + (bs + dt) * v

座標是(as + ct, bs + dt)^T, 也可以寫成

(a c  * (s 

 b d)     t)

也就是說只要對原空間座標(s, t)做一個矩陣變換就可以得到新的座標。 

我們將兩組基之間的轉換寫成矩陣的形式

(1 0  = (u v) (a c

 0 1)             b d)

那麼

(a c  = (u v)^-1

 b d) 

M = (u v 0 

       0 0 1)^-1

那麼,從規範基轉換到任意一組基(u, v),只需要一個變換矩陣M(任意兩組基之間的轉換可以修改上述推導得到)。

由於照相機空間的原點也不在原來空間的原點,我們還需要做一個平移。假設照相機的位置在p, 那麼

M_view = M * translationMatrix(-p) 

這樣我們先將將照相機放在原點,然後再進行基的轉換。

可以驗證,

M_view =  (u v p 

                0 0 1)^-1

實際上,當{u, v}是一組正交基時,M是一個轉動(rotation) 矩陣,即可得到

(u v 0        = (u v 0

 0 0 1)^-1      0 0 1)^T

這樣

M_view = (u v 0      * (I -p

               0 0 1)^T     0 1)

這個推導可以拓展到三維空間中,因此

M_view = (u v w 0      * (I -p

               0 0 0 1)^T     0 1) 

也就是在gluLookAt文件中的矩陣。