[WebGL入門]十三,minMatrix.js和座標變換矩陣

lufy發表於2014-08-07

注:文章譯自http://wgld.org/,原作者杉本雅広(doxas),文章中如果有我的額外說明,我會加上[lufy:],另外,鄙人webgl研究還不夠深入,一些專業詞語,如果翻譯有誤,歡迎大家指正。


座標變換矩陣的基本功能

進行基本的3D渲染的時候,需要準備3個座標變換矩陣,這個在之前的文章中說過很多次了。
第一個是模型變換矩陣,DirectX中叫做世界變換矩陣。模型變換矩陣影響的是所繪製的模型,模型的位置,模型的旋轉,模型的放大和縮小等相關的情況。
第二個是檢視變換矩陣,簡單來說,就是定義拍攝3D空間的鏡頭(攝像機),決定了鏡頭的位置,鏡頭的參考點,鏡頭的方向等。
第三個是投影變換矩陣,這個座標變換定義了螢幕的橫豎比例,剪下的領域等,另外獲取遠近法則的效果也需要用這個變換矩陣。
根據這些內容,差不多知道了需要對矩陣進行哪些操作。使用minMatrix.js可以對矩陣進行基本的操作,來看一下minMatrix.js都能完成哪些操作吧。


minMatrix.js的基本功能

本網站開發的minMatrix.js,包含矩陣的生成和矩陣的基本操作,minMatrix.js的核心是一個叫做matIV的物件,通過這個物件可以進行所有的矩陣操作,使用minMatrix.js來操作矩陣的時候,首先,需要生成一個matIV物件。

>生成matIV物件的程式碼

var m = new matIV();
像上面這樣,變數m就是matIV物件的一個例項,通過m.方法名可以呼叫matIV物件中存在的方法。
下面,列舉一下minMatrix.js中定義的matIV物件的方法,先不用馬上明白它們的意思,大致看一下就可以。

>>minMatrix.js:create
函式:matIV.create()
引數:
返回值:矩陣
生成一個4x4的方陣,裡面包含16個元素,其實是一個Float32Array物件,所有的元素都被初始化為0。

>>minMatrix.js:identity
函式:matIV.identity(dest)
引數:dest > 初始化的矩陣
返回值:初始化後的矩陣
將接收的矩陣引數進行初始化並返回。

>>minMatrix.js:multiply
函式:matIV.multiply(mat1,mat2,dest)
引數:mat1 > 相乘的原始矩陣
引數:mat2 > 作為乘數的矩陣
引數:dest > 用來儲存計算結果的矩陣
mat1在左,mat2在右,相乘後的結果儲存到dest中。

>>minMatrix.js:scale
函式:matIV.scale(mat,vec,dest)
引數:mat > 原始矩陣
引數:vec > 縮放向量
引數:dest > 用來儲存計算結果的矩陣
模型變換中的放大縮小,mat是原始矩陣,vec是X,Y,Z的各個縮放值組成的向量,最後的計算結果儲存在dest中。

>>minMatrix.js:translate
函式:matIV.translate(mat,vec,dest)
引數:mat > 原始矩陣
引數:vec > 表示從原點開始移動一定距離的向量
引數:dest > 用來儲存計算結果的矩陣
模型變換中的座標移動,mat是原始矩陣,vec是X,Y,Z的各個方向上的移動量組成的向量,最後將計算結果儲存到dest中。

>>minMatrix.js:rotate
函式:matIV.rotate(mat,angle,axis,dest)
引數:mat > 原始矩陣
引數:angle > 旋轉角度
引數:axis > 旋轉軸的向量
引數:dest > 用來儲存計算結果的矩陣
模型變換中的旋轉,mat是原始矩陣,angle是旋轉角度,axis是旋轉軸向量,最後將計算結果儲存到dest中。

>>minMatrix.js:lookAt
函式:matIV.lookAt(eye,center,up,dest)
引數:eye > 鏡頭位置向量
引數:center > 鏡頭參考點的向量
引數:up > 鏡頭的方向向量
引數:dest > 用來儲存計算結果的矩陣
檢視變換矩陣的生成,eye是鏡頭在三維空間中的位置,center是這個鏡頭的參考點,up是鏡頭的方向向量,最後將計算結果儲存到dest中。

>>minMatrix.js:perspective
函式:matIV.perspective(fovy,aspect,near,far,dest)
引數:fovy > 視角
引數:aspect > 螢幕的寬高比例
引數:near > 近截面的位置
引數:far > 遠截面的位置
引數:dest > 用來儲存計算結果的矩陣
投影變換矩陣的生成,這裡生成的是一般被稱為[透視射影]的投影變換矩陣,包含遠近法則。fovy是視角,aspect是螢幕的橫豎比例,near是近截面的位置(必須是大於0的數值),far遠截面的位置(任意數值),最後將計算結果儲存到dest中。

>>minMatrix.js:transpose
函式:matIV.transpose()
引數:mat > 原始矩陣
引數:dest > 用來儲存計算結果的矩陣
矩陣的行列互換,將計算結果儲存到dest中。

>>minMatrix.js:inverse
函式:matIV.inverse(mat,dest)
引數:mat > 原始矩陣
引數:dest > 用來儲存計算結果的矩陣
求矩陣的逆矩陣,mat是原始矩陣,求的的逆矩陣儲存到dest中。

只包含了特定的功能,所以設計的非常簡單。


矩陣變換的流程

使用minMatrix.js的話,可以操作矩陣,那麼先來確認一下操作順序。

模型變換也好,檢視變換,投影變換也好,如果不先生成矩陣的話,就什麼也做不了。所以首先執行matIV.create生成矩形,然後通過matIV.identity來初始化矩陣,程式碼如下。

>使用matIV物件初始化矩陣

// 生成matIV物件
var m = new matIV();

// 矩陣初始化
var Matrix = m.identity(m.create());
這樣的話,就可以使用Matrix變數了。
上面的程式碼同時執行矩陣的生成和初期化,向下面這樣分開執行也是可以的。

>使用matIV物件初始化矩陣(2)

var Matrix = m.create();
m.identity(Matrix);
然後用這個初始化完的矩陣,來執行自己想要的操作。比如,想使用模型矩陣將模型的座標向x方向移動一個1.0,程式碼如下。
>モデル変換行列に移動成分を與える例

var Matrix = m.identity(m.create());
m.translate(Matrix, [1.0, 0.0, 0.0], Matrix);
這樣的話,矩陣Matrix就成為經過了向x方向移動1.0的模型變換後的矩陣了。同樣,旋轉和縮放也是可以的。但是需要注意的是,移動,旋轉,縮放的執行順序。先移動後旋轉和先旋轉後移動的結果是有變化的。這是因為旋轉是以原點為中心的。所以要十分注意模型變換的執行順序。
具體的執行順序應該是,擴大縮小>旋轉>移動,這樣就能將縮放旋轉後的模型移動到正確的位置。

但是,這樣還沒有完。

OpenGL的矩陣使用列向量,相乘的順序正好相反。如果好好學習矩陣的計算方法的話就很容易明白了,列向量和行向量的相乘順序是完全相反的。也就是說,剛才的的順序 [擴大縮小>旋轉>移動] 得到的結果是完全不一樣的,正確的順序應該是[移動>旋轉>擴大縮小],所以生成模型變換矩陣的時候,順序要特別注意了。

檢視變換矩陣的生成使用matIV.lookAt函式,投影變換矩陣的生成使用matIV.perspective函式。

到這一步,模型,檢視,投影的各個變換矩陣都已經生成了,然後將三個矩陣相乘,生成最後的座標變換矩陣,陣列之間的相乘使用matIV.multiply函式。

但是,這裡有些需要注意的地方。

模型,檢視,投影的三個矩陣相乘的順序很重要,之前的文章(五,矩陣的基礎知識)也說明過了,矩陣相乘的順序如果改變的話,結果也會改變。雖然說普通的四則運算中求積的時候,左右交換順序得到的結果是一樣的,但是矩陣的話,結果就變了。

座標變換矩陣一般多使用模型,檢視,投影的英文單詞的第一個英文字母來表示,如mvpMatrix。相乘的順序不是mvp,而是p>v>m。使用minMatrix.js的話,程式碼例子如下。

>準備座標變換的例子

// 各種矩陣的生成和初始化
var mMatrix = m.identity(m.create());   // 模型變換矩陣
var vMatrix = m.identity(m.create());   // 檢視變換矩陣
var pMatrix = m.identity(m.create());   // 投影變換矩陣
var mvpMatrix = m.identity(m.create()); // 最終的座標變換矩陣

// 各個矩陣相乘的順序使用示例
m.multiply(pMatrix, vMatrix, mvpMatrix); // p和v相乘
m.multiply(mvpMatrix, mMatrix, mvpMatrix); // 然後和m相乘
使用到現在位置的步驟,生成座標變換矩陣之後,最終通知給WebGL,這個方法下回再說。

總結

這次介紹了一下本網站的矩陣計算的庫minMatrix.js的基本的使用方法,和座標變換矩陣的順序。

minMatrix.js通過一個叫做matIV的物件來對矩陣進行操作,各種方法的具體內容,現在不明白也不要緊,等必要的時候會進行具體的說明。生成了座標變換矩陣之後,離繪製多邊形還差一小步了。


下次,終於該讓多邊形顯示到畫面上了。


轉載請註明:轉自lufy_legend的部落格http://blog.csdn.net/lufy_legend

相關文章