一、概述
觀察空間經常被稱爲 OpenGL 的攝像機(Camera),所以有時也稱爲攝像機空間(Camera Space)或眼空間(Eye Space)。觀察空間是將世界空間座標轉化爲用戶視野前方的座標而產生的結果。因此觀察空間就是從攝像機的視角所觀察到的空間。而這通常是由一系列的位移和旋轉的組合來完成,平移/旋轉場景從而使得特定的對象被變換到攝像機的前方。這些組合在一起的變換通常存儲在一個觀察矩陣(View Matrix)裏,它被用來將世界座標變換到觀察空間,這一過程亦稱視圖變換。
二、定義一個相機
相機位置:Position
相機上方向:Up direction
相機觀察方向:Look-at direction
三、觀察矩陣(View Matrix)
這裏定義 爲相機的位置座標, 爲相機的上方向單位向量, 爲相機朝向單位向量。下面是得到一個觀察矩陣的步驟
- 將相機位置移動到原點
- 將 旋轉到 軸
- 將 旋轉到 軸
- 將 ( 叉乘 得到的向量)旋轉到 軸
根據定義變換矩陣可等價於
將相機移到原點可得平移矩陣
計算旋轉矩陣,這個過程太過複雜不好實現,但最終相機的方向與座標軸相同,所以我們可以先求出旋轉矩陣的逆矩陣。因此旋轉變換將 旋轉到 軸, 旋轉到 軸, 旋轉到 可轉換爲
旋轉到 , 旋轉到 , 旋轉到 ,最終結得到結果如下
如何校驗矩陣的正確性?這裏使用的都是單位向量,比如用 軸單位向量 與上述變換矩陣相乘,可得 ,其餘的校驗同理可得。根據矩陣的數學性質可得旋轉矩陣的最終結果爲
綜上可得
四、LookAt 函數
在圖形學中常使用 LookAt 函數來構造觀察矩陣,LookAt 方法需要需要一個位置、目標和上向量
inline mat4 LookAt(const vec4& eye, const vec4& at, const vec4& up)
{
vec4 n = normalize(eye - at); // 等價於上圖的 -g
vec4 r = vec4(normalize(cross(up, n)), 0.0); // g x t
vec4 t = vec4(normalize(cross(n, r)), 0.0); // t
vec4 d = vec4(0.0, 0.0, 0.0, 1.0);
mat4 c = mat4(r, t, n, d);
return c * Translate(-eye);
}
參考資料
[1]:Games101_Lecture_04:https://www.bilibili.com/video/BV1X7411F744?p=4
[2]:LookAt 函數源碼:https://github.com/WarZhan/Graphics-Demo/blob/master/Octahedra/mat.h
歡迎關注個人公衆號,實時推送最新博文!