這兩天終于閑了下來有時(shí)間寫點(diǎn)東西了,只記得想寫相機(jī)已經(jīng)是很久遠(yuǎn)的事情了,開發(fā)中涉及到相機(jī)相關(guān)的內(nèi)容也已經(jīng)是兩個(gè)月之前了。
在3D的世界里相機(jī)與矩陣是密不可分的,首先在投影之前,有模型矩陣和視圖矩陣,這兩者并沒有本質(zhì)上的區(qū)別,一個(gè)是站在模型的角度,另一個(gè)就是站在觀察者的角度了。模型的左移相當(dāng)于相機(jī)右移,有鑒于此,OPENGL中并不區(qū)分Model Matrix 和 View Matrix,而是將兩者統(tǒng)稱為ModelView Matrix.
以gluLookAt函數(shù)為例,該函數(shù)根據(jù)眼睛的位置,場景中心的位置,以及一個(gè)從觀察者視角向上的向量定一個(gè)視圖轉(zhuǎn)換,實(shí)際上做的還是應(yīng)用一個(gè)ModelView Matrix。原點(diǎn)位置和眼睛位置確定了z方向向量,向上的向量確定了y方向向量,兩者正交,叉積就是z方向向量了,這樣就可以確定一個(gè)視圖矩陣了。
相機(jī)不僅僅與ModelView Matrix有關(guān),而且也與投影矩陣有關(guān)系。有了相機(jī),再結(jié)合ViewPort大小,F(xiàn)OVy(Y方向Field Of View)或者Aspect Ratio,近裁減面,遠(yuǎn)裁減面就可以確定透視投影矩陣了。
一個(gè)4*4的矩陣如何與模型/視圖變換聯(lián)系起來呢?看這個(gè)圖,前三個(gè)列向量分別代表新坐標(biāo)系的x,y,z軸方向,而最后一個(gè)向量則代表平移量(新坐標(biāo)原點(diǎn)),而矩陣的(4,4)元素則是一個(gè)放大因子,他同時(shí)將所有點(diǎn)之間的距離放大。如果我們把一個(gè)四維向量與之相乘,就可以得到新的坐標(biāo)了。
什么是萬向節(jié)鎖(Gimbal Lock)呢?這是采用歐拉角的方式表示相機(jī)時(shí)出現(xiàn)的問題。這個(gè)問題源于繞軸旋轉(zhuǎn)時(shí)自由度的丟失。因?yàn)樾D(zhuǎn)到軸向時(shí)將無法確定是從哪個(gè)方向旋轉(zhuǎn)過來的。這就有點(diǎn)像是北極與南極點(diǎn)的經(jīng)度無法確定一個(gè)道理。而且在這個(gè)地方,可能出現(xiàn)角度的不連續(xù)變化。即直接從0度跳轉(zhuǎn)到180度。在相機(jī)方向平行于X軸向時(shí),繞X軸的旋轉(zhuǎn)不會有任何效果,也就是說,從數(shù)學(xué)上來講此時(shí)的ModelView Matrix始終是不變的。在計(jì)算時(shí),由于角度變化不連續(xù),所以計(jì)算的結(jié)果是很不穩(wěn)定的。例如漫游旋轉(zhuǎn)時(shí),簡單的增加角度,可能在某些臨界值上出現(xiàn)錯(cuò)誤的情況,典型的就是繞某一個(gè)軸的來回震蕩,這也就是所謂Lock的意義了吧。