Unity3D游戲開發(fā)常用算法:3D游戲開發(fā)中的矩陣詳解
前言
矩陣很多同學(xué)沒有接觸過,所以感覺很難,很復(fù)雜,其實(shí)只要學(xué)過矩陣的同學(xué)都知道,矩陣運(yùn)算并不難。今天我們給大家講講游戲開發(fā)中的矩陣的運(yùn)算。
1:矩陣是什么?
矩陣是描述線性變換的一種數(shù)學(xué)工具,線性變換指的是使用一次函數(shù)從一個(gè)空間變換到另外一個(gè)空間。
例如在空間A中的一個(gè)2維向量(xa, ya)變換到空間B,使用一次線性函數(shù)變換后得(xb, yb)。
xb = A*xa + B*ya + C;
yb = M*xa + N*ya + D;
?
上述變換中,xb 是由xa, ya 經(jīng)過線性運(yùn)算而得到得。如果xb = A*xa^2 + B*ya + C,這樣就不是線性變換了。
數(shù)學(xué)前輩們?yōu)榱嗣枋錾厦娴木€性變換,發(fā)明了矩陣,把上面的變換標(biāo)記為:

上面的變換,(xa, ya)通過矩陣變換到(xb, yb),用矩陣是如何變換的呢?我們實(shí)際就是把(xa, ya)*矩陣 = (xb, yb)。
?
2: 向量與矩陣, 矩陣與矩陣的乘法;
向量與矩陣乘法:
按照上述的例子我們一起來計(jì)算一下,空間Va的向量(xa, ya), 變換到空間Vb的向量(xb, yb)
(1): 擴(kuò)展向量的維度為3維, (xa, ya)變成了(xa, ya, 1)
(2): 計(jì)算(xa, ya, 1) * 矩陣

總結(jié)一下向量與矩陣的乘法規(guī)則:
新向量的第i個(gè)元素,等于原來向量的每個(gè)元素與第i列矩陣的每個(gè)對應(yīng)數(shù)據(jù)相乘后相加。由這個(gè)規(guī)則,我們可以得到向量與矩陣相乘向量的維度必須和矩陣的行數(shù)一樣。
?
很多同學(xué)馬上就會有疑問了,矩陣既然最后還是要結(jié)合元素計(jì)算,我干嘛還要用矩陣呢?直接算不就可以么?接下來矩陣得第二個(gè)妙處就在于每個(gè)線性變化都對應(yīng)一個(gè)矩陣,我們可以把多次線性變換疊加起來,這樣就可以減少運(yùn)算的次數(shù)。比如我要把100個(gè)點(diǎn),由V1空間,變換到v2空間,再變換到v3空間。V1到v2對應(yīng)一個(gè)矩陣,v2到v3對應(yīng)一個(gè)矩陣,我們可以把這兩個(gè)矩陣變換疊加起來變成一個(gè)矩陣。100個(gè)點(diǎn),每個(gè)點(diǎn)計(jì)算一次矩陣乘法即可得到新的點(diǎn),而不用每個(gè)點(diǎn)計(jì)算2次矩陣乘法得到新的點(diǎn)。
如何把多個(gè)矩陣對應(yīng)的多次線性變換疊加起來呢?這個(gè)就是矩陣與矩陣的乘法。例如
?

根據(jù)上面的規(guī)律,新矩陣的對應(yīng)第i行第j列元素,我們叫做元素ij。矩陣變化的疊加就是矩陣乘法,矩陣乘法的計(jì)算規(guī)則如下:
A矩陣*B矩陣=C矩陣, Cij = Ai0*Bj0 + Ai1*Bj1 + ….. ;即Cij為A的第i行與B的第j列的每項(xiàng)數(shù)據(jù)相乘后的和(即dot(Ai, Bj))。根據(jù)上面的規(guī)則,我們發(fā)現(xiàn)兩個(gè)矩陣要能相乘必須要滿足一個(gè)條件,就是左邊矩陣的列數(shù)等于右邊矩陣的行數(shù),否者兩個(gè)矩陣是無法相乘的。
?
3: 游戲開發(fā)中的縮放,旋轉(zhuǎn)平移矩陣;
游戲開發(fā)中常用的線性變換有縮放,平移, 旋轉(zhuǎn), 這個(gè)我們通常叫做transform。而這些變換疊加在一起,就是我們在游戲世界中擺放游戲物體,我們可以把每個(gè)物體的線性變換,疊加在一起,形成一個(gè)矩陣,然后我們再來做坐標(biāo)變換。
先來看平移矩陣,我們以2D為例, 向量(x, y)平移變換到新的空間,平移就是把x, y都加上一個(gè)常量。那么平移變換矩陣為
?

?
縮放矩陣: 向量(x, y)通過縮放,到新的空間
?

我們疊加在一起運(yùn)算一下, 先縮放還是先平移,得到的結(jié)果不一樣,先平移后縮放的結(jié)果是 (x, y, 1) 先平移dx, dy, 后縮放3倍,(3x+3*dx, 3y + 3*dy, 1), 先縮放后平移, 得到的結(jié)果是(3x+dx, 3y + dy, 1)。
我們反應(yīng)到矩陣,先平移后縮放,平移矩陣*縮放矩陣,如下:

同理,如果是先縮放后平移,縮放矩陣*平移矩陣,如下:

同樣是兩個(gè)矩陣,乘法的位置不一樣,得到的結(jié)果可能不一樣。
?
4: 3D游戲中的旋轉(zhuǎn)矩陣,單位矩陣, 逆矩陣;
平移縮放,大家都好理解了,旋轉(zhuǎn)矩陣不那么直觀,特別是3D的。我們以大家熟悉的歐拉旋轉(zhuǎn)為例。
比如我們在3D里面先繞x軸旋轉(zhuǎn) a度,再繞y軸旋轉(zhuǎn)b度,再繞z軸旋轉(zhuǎn)c度。這個(gè)其實(shí)就是3個(gè)空間的變換,每次變換,都對應(yīng)一個(gè)旋轉(zhuǎn)矩陣,然后我們按照順序把這三個(gè)矩陣疊加起來 Rx * Ry * Rz = R旋轉(zhuǎn)。根據(jù)我們上面的分析,矩陣的位置不一樣,得到的結(jié)果會不一樣,所以每個(gè)游戲引擎的歐拉角旋轉(zhuǎn)都會有一個(gè)固定的順序來計(jì)算, 最終就得到一個(gè)旋轉(zhuǎn)矩陣。

最后說幾個(gè)比較特殊的矩陣,單位矩陣,就是乘以這個(gè)矩陣后不會發(fā)生任何改變,相當(dāng)于沒有變化。
逆矩陣: 矩陣A的反向矩陣叫A的逆矩陣即: A矩陣*A的逆矩陣=單位矩陣, 兩個(gè)互為逆矩陣的疊加在一起,相當(dāng)于沒有變化。
今天的矩陣就講解到這里,關(guān)注我, 在我們公開課中可以免費(fèi)獲得矩陣的視頻講解的課程。
附:視頻教程
https://www.bycwedu.com/promotion_channels/2146264125? ?