一: 攝像機
- OpenGL本身沒有攝像機(Camera)的概念,但我們可以通過把場景中的所有物體往相反方向移動的方式來模擬出攝像機,產生一種我們在移動的感覺,而不是場景在移動。
- 以攝像機的視角作為場景原點時場景中所有的頂點坐標:觀察矩陣把所有的世界坐標變換為相對於攝像機位置與方向的觀察坐標。
- 要定義一個攝像機,我們需要它在世界空間中的位置、觀察的方向、一個指向它右測的向量以及一個指向它上方的向量。
- 實際上創建了一個三個單位軸相互垂直的、以攝像機的位置為原點的坐標系。
- 攝像機位置:攝像機位置簡單來說就是世界空間中一個指向攝像機位置的向量。
glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f);
- 攝像機方向:這里指的是攝像機指向哪個方向。現在我們讓攝像機指向場景原點:(0, 0, 0)。
2.1 用場景原點向量減去攝像機位置向量的結果就是攝像機的指向向量。
2.2 由於我們知道攝像機指向z軸負方向,但我們希望方向向量(Direction Vector)指向攝像機的z軸正方向。如果我們交換相減的順序,我們就會獲得一個指向攝像機正z軸方向的向量:
glm::vec3 cameraDirection = glm::normalize(cameraPos - cameraTarget);//方向向量,與指向的方向相反的向量 ```
2.3 ** 方向向量 **:(與實際指向的方向相反)方向向量(Direction Vector)並不是最好的名字,因為它實際上指向從它到目標向量的相反方向(注意看前面的那個圖,藍色的方向向量大概指向z軸的正方向,與攝像機實際指向的方向是正好相反的)。
3. 右軸:需要的另一個向量是一個**右向量(Right Vector)**,它代表攝像機空間的x軸的正方向。為獲取右向量我們需要先使用一個小技巧:先定義一個**上向量(Up Vector)**。接下來把上向量和第二步得到的方向向量進行叉乘。兩個向量叉乘的結果會同時垂直於兩向量,因此我們會得到指向x軸正方向的那個向量(如果我們交換兩個向量叉乘的順序就會得到相反的指向x軸負方向的向量):
``` glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f);
glm::vec3 cameraRight = glm::normalize(glm::cross(up, cameraDirection)); ```
4. 上軸:已經有了x軸向量(cameraRight)和z軸向量(cameraDirection),獲取一個指向攝像機的正y軸向量就相對簡單了:我們把右向量和方向向量進行叉乘:
```glm::vec3 cameraUp = glm::cross(cameraDirection, cameraRight); ```
二:LookAt矩陣
1. 使用矩陣的好處之一是如果你使用3個相互垂直(或非線性)的軸定義了一個坐標空間,你可以用這3個軸外加一個平移向量來創建一個矩陣,並且你可以用這個矩陣乘以任何向量來將其變換到那個坐標空間。
2. 有了3個相互垂直的軸和一個定義攝像機空間的位置坐標,可以創建自己的LookAt矩陣
3. LookAt矩陣就像它的名字表達的那樣:它會創建一個看着(Look at)給定目標的觀察矩陣。
4. ***位置向量在矩陣中運算時時相反的:因為我們最終希望把世界平移到與我們自身移動的相反方向。***
5. glm::LookAt函數需要一個位置、目標和上向量。它會創建一個和在上一節使用的一樣的觀察矩陣。***(根據以上的分析,有了這三個向量足以構建出LookAt矩陣)***
``` glm::mat4 view;
view = glm::lookAt(glm::vec3(0.0f, 0.0f, 3.0f), //攝像機的位置向量
glm::vec3(0.0f, 0.0f, 0.0f), //目標位置向量
glm::vec3(0.0f, 1.0f, 0.0f));//上向量 ```
6. 攝像機類里面返回的觀察矩陣定義如下:
``` view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp); ```這里的目標位置改成了**攝像機位置加上方向向量**(glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f);)這樣做可以保證,攝像機始終注視着目標方向。
三: 視角移動
1. 為了能夠改變視角,我們需要根據鼠標的輸入改變***cameraFront***向量(上面說的方向向量:cameraDirection)。
2. 歐拉角:俯仰角(Pitch)、偏航角(Yaw)和滾轉角(Roll)
2.1 俯仰角(Pitch):如何往上或往下看的角,**繞x軸**
2.2 偏航角(Yaw):偏航角表示我們往左和往右看的程度,**繞y軸**
2.3 滾轉角(Roll):如何翻滾攝像機,**繞z軸**