上次說到渲染管線的一般組成,接下來就要說說各部分的轉(zhuǎn)換怎么做了。
在這之前,本著掃盲的態(tài)度,先介紹一點(diǎn)矩陣的基礎(chǔ)知識(shí)。
大學(xué)一年級(jí)一般都會(huì)上一門叫做“線性代數(shù)”的課,這個(gè)課上就會(huì)講很多關(guān)于線性方程組(可以先不管“線性”兩個(gè)字,初等數(shù)學(xué)里的東西基本都是線性的),關(guān)于矩陣的東西。
首先,什么是線性方程組?
ax + by + c = 0 a b c
dx + ey + f = 0 這個(gè)就是一個(gè)線性方程組, d e f
gx + hy + i = 0 我們可以把它表示成矩陣 g h i
再來,什么是向量?一個(gè)1 x N 的矩陣,就是一個(gè)向量,例如
a
b 一般可以記成(a,b,c)
c
線性代數(shù)對(duì)矩陣定義了一系列的運(yùn)算方法,比如乘法,加法等。具體的定義最好找本線性代數(shù)來看看,另外推薦一個(gè)《理解矩陣》,是個(gè)短小精悍的文章,對(duì)于理解矩陣,坐標(biāo)系,向量比較有好處。
現(xiàn)在就先說明幾個(gè)問題。
1、一個(gè)N維向量,可以表示一個(gè)N維空間的點(diǎn)。比如說(1,2)在平面直角坐標(biāo)系表示x=1,y=2的點(diǎn)
2、可以同時(shí)存在多個(gè)坐標(biāo)系。例如,有兩個(gè)坐標(biāo)系,重疊在一起,但是坐標(biāo)系A(chǔ)的單位長(zhǎng)度是坐標(biāo)系B單位長(zhǎng)度的2倍。那么在A坐標(biāo)系中的 (1,0)點(diǎn),在B坐標(biāo)系中就是 (2,0)點(diǎn)
3、坐標(biāo)系原點(diǎn)位置可以不同。比如,坐標(biāo)系A(chǔ)原點(diǎn)在坐標(biāo)系B的 (1,1)處,那么坐標(biāo)系A(chǔ)的(1,0)點(diǎn)就是坐標(biāo)系B的(2,1)點(diǎn)。
4、坐標(biāo)系可以表示成矩陣。 比如 2 0 就表示一個(gè)x軸縮小一半的坐標(biāo)系。這個(gè)坐標(biāo)系實(shí)際上是由
0 1
0 1
然,1 0就是一個(gè)我們平常使用的坐標(biāo)系。至于另外那兩個(gè)數(shù)要是不為0會(huì)發(fā)生什么情況,可以自己想
0 1
想,我后面也會(huì)解釋。
5、三維空間的坐標(biāo)系可以表示成3x3矩陣。(這個(gè)不用解釋了吧)
6、坐標(biāo)系矩陣與對(duì)應(yīng)維數(shù)的向量相乘,將得到該向量在這個(gè)坐標(biāo)系下的表示。這個(gè)是最關(guān)鍵的一個(gè)點(diǎn),能理解,后面就都好辦了。一個(gè)向量 (2,2,2) ,一個(gè)矩陣(坐標(biāo)系)2 0 0 ,用矩陣乘以這個(gè)向量,
0 2 0
0 0 2
根據(jù)矩陣乘法,我們將得到向量(4,4,4) 。關(guān)于這一點(diǎn),大家可以看看《理解矩陣》,它的描述比我說得更透徹,其實(shí)矩陣還表達(dá)了一種映射關(guān)系,或者表達(dá)了一種變換。
7、坐標(biāo)系矩陣還可以擴(kuò)展,用來表示坐標(biāo)系原點(diǎn)的位置。這種擴(kuò)展的坐標(biāo)系矩陣看起來就像這個(gè)樣子1 0 0 1 這是就是所謂的“三維空間的齊次坐標(biāo)系”。為什么叫“齊次”,我還沒理解透,以后理解
0 1 0 1
0 0 1 0
0 0 0 1
了再補(bǔ)上。這個(gè)矩陣描述的坐標(biāo)系是這樣的: 坐標(biāo)系的x,y,z軸的單位向量都與我們最常見的那種坐標(biāo)系一樣,原點(diǎn)在(-1,-1,0)處。也就是,最右邊一列多出來的,就是表達(dá)原點(diǎn)位置的向量。那么這個(gè)矩陣怎么做乘法呢,因?yàn)楦鶕?jù)矩陣乘法,這個(gè)矩陣需要乘以一個(gè)4維向量。假設(shè)有一個(gè)點(diǎn)(1,1,1),那么我們就在這個(gè)向量后面再增加一個(gè)數(shù),變成 (1,1,1,1),然后就可以去乘這個(gè)矩陣了(關(guān)于這個(gè)硬加上的數(shù),見下一點(diǎn))。
8、上面說到齊次坐標(biāo)系,還說到了一個(gè)三維向量增加一維變成4維,那么這個(gè)第四維是什么含義呢?當(dāng)一個(gè)向量表達(dá)齊次坐標(biāo)時(shí),它的最后一維有特殊的含義。一個(gè)4維向量V (a,b,c,h),當(dāng)h = 0 時(shí),V表示一個(gè)三維空間中的向量。當(dāng)h 不為 0 時(shí),V表示一個(gè)三維空間中的點(diǎn)。這個(gè)點(diǎn)的坐標(biāo)是 (a/h,b/h,c/h)。在進(jìn)行矩陣運(yùn)算時(shí),第四維正常的參與運(yùn)算,我們可以得到簡(jiǎn)單的推論:
向量加向量得到向量。 向量得到點(diǎn)。 點(diǎn)加點(diǎn)得到中點(diǎn)。
在此補(bǔ)充一點(diǎn),在空間中,“點(diǎn)”和“向量”其實(shí)是不同的概念,向量有方向,但沒位置,點(diǎn)有位置但沒方向。所以在齊次坐標(biāo)系矩陣中,第四列第四行是1,因?yàn)樵c(diǎn)是一個(gè)點(diǎn),不是向量。
9、在計(jì)算機(jī)圖形學(xué)中,一般就是用矩陣來做各種物體的坐標(biāo)變換,方法很簡(jiǎn)單,就是用一個(gè)矩陣去乘以表示坐標(biāo)的向量。
10、矩陣的表示方法還有一種,就是向量按行表示,線性方程組矩陣就是這樣。也就是一行表示一個(gè)向量。所以看其它資料的時(shí)候要注意一下。
說了一這么些數(shù)學(xué),估計(jì)也看煩了,那么就先講一個(gè)實(shí)例:世界坐標(biāo)變換。
世界坐標(biāo)變換是渲染管線生成世界模型時(shí)的必備操作。
比如說,我有一個(gè)正方體,頂點(diǎn)坐標(biāo)為(1,1,1),(1,1,-1),(1,-1,1),(1,-1,-1),(-1,1,1),(-1,1,-1),(-1,-1,1),(-1,-1,-1)。 然后我需要在這個(gè)世界模型中放置很多個(gè)正方體,怎么辦呢?總不能手工的去輸入那么多的坐標(biāo)吧。我只能對(duì)這個(gè)正方體作一些變換,比如:放大縮小,旋轉(zhuǎn),移動(dòng)。通過這樣一些操作,我就可以把這個(gè)正方體放到任何地方了。那么現(xiàn)在簡(jiǎn)單說怎么實(shí)現(xiàn)。
這個(gè)正方體,我們存儲(chǔ)的時(shí)候就存下8個(gè)點(diǎn)就夠了,這8個(gè)點(diǎn)都各自是一個(gè)4維齊次向量,可以用靜態(tài)數(shù)組來實(shí)現(xiàn)。然后構(gòu)造一個(gè)矩陣,依次乘以這8個(gè)點(diǎn),那么一次變換就算做完了。
放大縮小,我們就構(gòu)造這樣的矩陣 2 0 0 0 ,這樣就把正方體放大一倍
0 2 0 0
0 0 2 0
0 0 0 1
旋轉(zhuǎn): 這個(gè)相對(duì)比較復(fù)雜一點(diǎn),在這里的旋轉(zhuǎn)我們會(huì)說 繞x軸旋轉(zhuǎn) a 弧度(角度),相應(yīng)的矩陣為
1 0 0 0
0 cosa sina 0
0 -sina cosa 0
0 0 0 1
平移: 把正方體中心移動(dòng)到(1,2,3),矩陣為 1 0 0 1
0 1 0 2
0 0 1 3
0 0 0 1
一般情況下我們應(yīng)該按照這樣的順序來做這三種變換: 縮放、旋轉(zhuǎn)、平移。 如果改變順序,那么轉(zhuǎn)換出來的效果也將不一樣,有興趣的可以自己計(jì)算一下。
暫時(shí)就這么多吧,下次繼續(xù)說~