[圖形學學習]OpenGL視圖矩陣變換


模型矩陣

模型坐標

這個三維模型,是由一組頂點定義的。頂點的XYZ坐標是相對於物體中心定義的:也就是說,若某頂點位於(0, 0, 0),它就在物體的中心。

也許玩家需要用鍵鼠控制這個模型,所以我們希望能夠移動它。這簡單,只需學會:縮放旋轉平移就行了。在每一幀中,用算出的這個矩陣,去乘(在GLSL中乘,不是C++中!)所有的頂點,物體就動了。唯一不動的就是世界坐標系(World Space)的中心。

世界坐標

現在,物體所有頂點都位於世界坐標系。下圖中黑色箭頭的意思是:從模型坐標系(Model Space)(頂點都相對於模型的中心定義)變換到世界坐標系(頂點都相對於世界坐標系中心定義)。

視圖矩陣

視圖坐標

此圖展示了:從世界坐標系(頂點都相對於世界坐標系中心定義)到觀察坐標系(Camera Space,頂點都相對於相機定義)的變換。

GLM使用了glm::LookAt函數來計算這個變換矩陣:

glm::mat4 CameraMatrix = glm::LookAt(
    cameraPosition, // the position of your camera, in world space
    cameraTarget,   // where you want to look at, in world space
    upVector        // probably glm::vec3(0,1,0), but (0,-1,0) would make you looking upside-down, which can be great too
);

視圖變換矩陣推導

我們希望得到模型在觀察坐標系上的坐標,只需要對模型的坐標進行矩陣變換,而這個矩陣其實就是觀察坐標系變換為世界坐標系的矩陣。
如glm::LookAt函數的參數所示,根據前兩個參數我們可以得到一個向量a,即由相機望向目標的向量,而由第三個參數得到一個向量b,即相機的朝向。

如圖中所示,根據a,b向量可以得到3個互相正交的單位向量,也就是一組正交基,這就是我們的觀察坐標系。

如圖的正交矩陣,與(Xu,Yu,Zu)相乘得到(1,0,0),與(Xv,Yv,Zv)相乘得到(0,1,0),與(Xw,Yw,Zw)相乘得到(0,0,1)。
所以我們可以將這個矩陣當做是由uvw坐標轉換為xyz坐標的旋轉矩陣

。但在做旋轉之前我們首先需要將uvw坐標軸的原點由camera的位置移至xyz坐標軸的原點。

因此需要先左乘一個平移矩陣,再乘旋轉矩陣,如圖,我們得到了坐標軸變換矩陣,也即glm::LookAt函數中的變換矩陣。

旋轉矩陣補充

在三維旋轉理論體系中,羅德里格旋轉公式(根據歐林·羅德里格命名)是在給定轉軸和旋轉角度后,旋轉一個向量的有效算法。如果v是在{R}^3中的向量,k是轉軸的單位向量,θ是旋轉角度(根據叉乘的方向確定正負號),那羅德里格旋轉公式表達為:

矩陣形式:

示例代碼:

mat3 Transform::rotate(const float theta, const vec3& axis) {
       auto axis1 = glm::normalize(axis);
       auto x = axis1[0],y=axis1[1],z=axis1[2];
       mat3 mtx1(1,0,0,0,1,0,0,0,1);
       mat3 mtx2(x*x,x*y,x*z,x*y,y*y,y*z,x*z,y*z,z*z);
       mat3 mtx3(0,z,-y,-z,0,x,y,-x,0);
       mat3 mtx = cos(theta)*mtx1 +(1-cos(theta))*mtx2+sin(theta)*mtx3;
       return mt; }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM