OSG相機-基礎篇
在計算機的三維世界中,相機如同我們的眼睛,捕捉眼前的每一副畫面,反過來物體要能夠被相機在指定的距離和角度下觀看到,并通過屏幕像素繪制出來。
在這個過程中,物體的三維空間坐標需要經過好幾層矩陣變換,最終轉換到二維平面坐標,并通過像素呈現在屏幕中。我們將這幾層矩陣變換過程簡稱為MVPW矩陣變換。
下面我們展開介紹MVPW具體內容 ~
模型(Model)
MVPW中的M是模型頂點在三維場景中的位置。
一般情況下,模型在繪制過程中都是使用模型自身坐標(通常稱為模型坐標或者小坐標),模型的頂點位置稱為pos,通過變換矩陣 matrix改變模型位置、姿態、大小,將模型放置在指定的三維場景中。這時候模型頂點在三維場景中的坐標位置worldPos = pos * matrix。
觀察矩陣(ViewMatrix)
MVPW中的V是觀察矩陣,作用是將世界坐標轉為為相機坐標。在相機坐標系下,以相機作為參考,其位置為原點,world* viewMatrix可獲得模型頂點在相機坐標下的位置。
在osg中觀察矩陣接口設置如下:

其中eye是相機的世界坐標位置,center是相機觀察的位置,up是相機向上向量。

我們可以通過建立坐標軸來說明,在相機坐標系下,eye與center的方向構建出的向量為前向量F,即Y軸;F向量與up進行叉乘后得到右向量R,即X軸;R向量與F向量叉乘后的得到up向量U,即Z軸。此時相機坐標系的XYZ軸就建立完成了。

圖1:相機坐標軸
osg中viewMatrix視口矩陣的計算:

根據viewMatrix的逆矩陣獲取相機坐標軸、相機位置:

圖2:視口逆矩陣結構

在FreeXEarth中第一人稱操作器、第三人稱操作器、地球操作器都是通過對視口矩陣平移、旋轉等操作實現的。
投影矩陣(ProjectMatrix)
MVPW中的P是投影矩陣(projectMatrix), 在計算機三維圖像中,投影的作用是將三維坐標信息轉化到二維坐標中。投影有兩種:透視投影和正交投影。
正交投影可以讓視口中物體之間的距離在投影變化前后都保持不變,也可以按照實體原始比例繪制到屏幕中。

圖3:正交投影視景體(長方體)
例如,兩條平行線投影變換后仍然保持平行,不會出現遠處的物體變小近處的較大。
在osg中設置正交投影的接口如下:

left表示視景體左面的坐標,right表示右面的坐標,bottom表示下面的,top表示上面的。
透視投影是在相機坐標下裁剪一塊四棱錐區域,通過視口變換到一個(-1,1)的正方體中,最終將正方體信息投影到四棱錐的前面上。通過透視投影變換后的實體呈現出近處大遠處小效果。透視投影跟人的眼睛或相機鏡頭觀察到的效果是一致的。

圖4:透視投影視景體(四棱錐)
在osg中設置透視投影的接口如下:

fovy——相機的角度大小,視角小就是焦距大(長焦),視角大就是焦距小(廣角);
aspect——實際窗口的縱橫比,即width(窗口寬度)/ height(窗口高度);
zNear——近處裁面,如果物體的位置到相機距離小于近裁剪面,該物體會被相機裁剪掉;
zFar——遠處的裁面,如果物體的位置到相機距離大于遠裁剪面,該物體會被相機裁剪掉。

圖5:fovy, aspectRatio, zNear關系圖
根據三角函數,通過fovy, aspectRatio,zNear, zFar可以計算出left、right、top、bottom:

最終根據left、right、top、bottom、zNear, zFar計算投影矩陣:

窗口矩陣變化(Windows)
其中當三維坐標經過了MVP轉換后,還需要經過窗口變換,才能顯示在屏幕中。
窗口矩陣變換主要作用是將視口裁剪后的結果映射到屏幕中,通過viewport獲取屏幕顯示區域的大小,將幀緩沖區域內的數據轉變為能顯示在屏幕上的像素。
在osg/opengl矩陣變換工作流程一般如下圖:

圖6:矩陣變換工作流程
當數據進行MVP矩陣轉換后,得到裁剪坐標,在經過坐標除以w之后(稱為透視除法),會得到標準化設備坐標(NDC),標準化設備坐標是一個x、y和z值在-1.0到1.0的一小段空間。
任何落在范圍外的坐標都會被丟棄/裁剪,不會顯示在你的屏幕上,最終將x、y分別于viewport中顯示的寬度、高度相乘,得到最終的屏幕坐標。整個過程也是世界坐標轉換為屏幕坐標的過程!

圖7:標準化設備坐標
osg中將世界坐標的轉換為屏幕坐標,具體代碼如下:

一起回顧
最后,讓我們一起回顧MVPW的整個過程:
M用來模型位置變換,調整模型位置,變換后的物體坐標是全局坐標,也成為世界坐標;
V是相機的視口變換,用來構建相機視口坐標系,將物體全局坐標轉換為相機坐標中;一般我們將模型變換與視口變換統稱為模型視口變換,即modelView;
P是投影變換,構建一個裁剪的視景體,或長方體或四棱錐,對場景進行裁剪;
W是窗口變換,作用是將幀緩沖區域內的數據轉變為能顯示在屏幕上的像素。
到此,
MVPW的矩陣變換已經完成,
我們以此作為相機基礎篇的開端!
非常感謝大家閱讀,
以后我們會結合FreeXEarth產品應用為大家帶了更好的作品~