1. 程式人生 > >右手座標系下LookAt檢視矩陣的推導

右手座標系下LookAt檢視矩陣的推導

基本知識

右手座標系

右手手掌彎曲,手指方向由正X軸指向正Y軸,如果這時Z軸正方向與大拇指方向保持一致,座標系為右手座標系,否則為左手座標系。

向量叉乘的方向

向量(1,0,0)與向量(0,1,0)叉乘的結果可以由公式計算得到為(0,0,1),在數值上它是始終不變的。但放在座標中進行解釋,(0,0,1)都是代表Z軸正方向,但在左右手座標系中他們與X,Y軸正方向的相對空間位置是不同的。在右手座標中判斷叉乘結果的方向使用右手定律,左手座標系中使用左手。

檢視變換是三維渲染中物體頂點座標變換的一部分,完整的流程為:

1使用Module矩陣將物體頂點座標從物體座標系轉換至世界座標系

2使用View矩陣將物體頂點座標從世界座標系轉換至由攝像機定義的座標系,攝像機座標系原點在攝像機,Z軸方向沿著視線方向往前,y軸方向即攝像機的向上向量。

3.使用透視投影矩陣及透視除法將位於視錐體內的頂點座標轉換到X,Y,Z範圍都為-1至1.

攝像機特點:

    三維自由運動的物體有六個運動自由度,分別是X,Y,Z方向的平移和繞X,Y,Z軸的選擇。繞Z軸的旋轉使物體發生側向傾斜,如果站在人的角度考慮的話,就是向左或向右傾斜了,這個自由度在大部分情況是可以不要的,他更容易使人產生眩暈感。所以這裡的攝像機擁有剩餘的五個自由。繞X軸選擇代表了仰視和俯視,繞Y軸旋轉代表了旋轉自身,比如從向東旋轉到向西。

View矩陣的工作原理

    View矩陣的工作目標是將世界座標系中的所有物體的頂點的座標從世界座標系轉換到攝像機座標系。

  攝像機座標系的原點不一定與世界座標系重合,同時由於自身的旋轉,座標軸也一定不與世界座標系的座標軸平行。為完成工作任務,需要分為兩步走1.整體平移,將攝像機平移至世界座標系原點,2.將座標點從世界座標系轉換至攝像機座標系。

    使用單位向量U,V,W分別代表攝像機座標系X,Y,Z軸正向的單位向量在世界座標系中的表示,則在攝像相機座標系與世界座標系原點重合的情況下,物體頂點座標代表的向量(即從世界原點指向物體頂點的向量)在U,V,W上的投影大小即是物體頂點在攝像機座標系下的座標值。因為U,V,W是單位向量,使用二者的點乘即可以得到頂點的投影大小。

Lookat函式的一般形式

LookAt(Vector3 eyePos,Vector3 targerPos,Vector3 upDir,Matrix4 & ViewMatrix);

函式的引數:eyePos代表了攝像機在世界座標系中的座標,targetPos代表了視線方向上某個目標物體的座標,upDir一般使用的是世界座標系中的向上向量,即(0,1,0).

這個函式將傳入的最後一個引數設定為前面引數所指定的View矩陣。

首先要先求得攝像機座標系的U,V,W。

1.首先已知eyePos和tarPos,可以求得視線方向,視線方向由eyePos指向tarPos,所以viewDir=tarPos-eyePos,W=viewDir.normalize()

2.U=crossProduct(upDir,W) U=U.normalize()

upDir一般是向量(0,1,0),所以求得的U向量必然是平行於地面,而如果物體繞Z軸選擇,X軸將不再平行於地面。說明使用upDir為(0,1,0)時計算U,V,W的計算方法預設攝像機只有兩個旋轉自由度。

3.V=crossProduct(W,U) V.normalize()

注意:這裡使用右手座標系,使用向量叉積計算U,V時,crossProduct()函式的引數的順序是重要的。叉乘結果向量的方向符合右手法則。

現在View矩陣可以由兩個矩陣合成,一個是將攝像機平移至原點的矩陣T,一個是將座標點從世界座標系轉換至攝像機座標系的矩陣R。

 

大概的程式碼表示的流程