第三章 學習Shader所需的數學基礎(2)

2021-09-19 05:16:18 字數 3030 閱讀 4383

我們在以前渲染流水線中就接觸了座標空間的變換。例如,在學習頂點著色器流水線階段時,我們說過,頂點著色器的最基本功能就是把模型的頂點座標從模型空間轉換到齊次裁剪座標空間中。

我們先要為後面的內容做些數學鋪墊。在渲染流水線中,我們往往需要把乙個點或方向向量從乙個座標空間轉換到另乙個座標空間。這個過程到底是怎麼實現的?

我們把問題一般化,我們知道,要想定義乙個座標空間,必須指明其原點的位置和三個座標軸的方向。而這些數值實際上是相對於另乙個座標空間的(讀者需要記住,所有的都是相對的)。也就是說,座標空間會形成乙個層次結構——每個座標空間都是另乙個座標空間的子空間,反過來說,每個空間都有乙個**父(parent)**座標空間。對座標空間的變換實際上就是在父空間和子空間之間對點和向量進行變換。

假設現在有父座標空間p以及乙個子座標空間c。我們知道父座標空間中子座標空間的原點位置以及3個單位座標軸。我們一般會有兩種需求:一種需求是把子座標空間下表示的點或向量ac轉換到父座標空間下的表示ap,另乙個需求是反過來,即把父座標空間下表示的點或向量bp轉換到子座標空間下的表示bc。我們可以通過下面的公式來表示這兩種需求:

其中,mc->p表示的是從子空間轉換到父空間的變換矩陣,而mp->c是其逆矩陣(即反向變換)。那麼現在的問題是,如何求解這些變換矩陣?事實上,我們只要求出二者之一即可,另乙個矩陣可以通過求逆矩陣的方式來得到。

下面,我們來講解如何來求出從子座標空間到父座標空間的變換矩陣mc->p。

首先,我們來回顧乙個看似很簡單的問題:當給定乙個座標空間以及其中一點(a,b,c)時,我們是如何知道該點的位置呢?我們可以通過四個步驟來確定它的位置。

(1)從座標原點開始

(2)向x軸方向移動a個單位

(3)向y軸方向移動b個單位

(4)向z軸方向移動c個單位

需要說明的是,上面的步驟只是我們的想象,這個點實際沒有發生移動。上面的步驟看起來再簡單不過了,座標空間的變換就蘊含在上面的4個步驟中。現在,我們已知座標空間c的三個座標軸在父座標空間p下的表示xc,yc,zc,以及原來的原點oc。當給定乙個子座標空間中的一點ac=(a,b,c),我們同樣可以依照上面4個步驟來確定其在父座標空間下的位置ap:

(1)從座標的原點開始

這很簡單,我們已經知道了子座標空間的原點位置oc。

(2)向x軸方向移動a個單位

仍然很簡單,因為我們已經知道了x軸的向量表示,因此可以得到

(3)向y軸方向平移b個單位

同樣的道理,這一步就是:

(4)向z軸方向平移c個單位

最後就可以得到

現在,我們已經求出了mc->p!什麼?你沒看出來嗎?我們再來看一下最後得出的式子:

你們可能會問,這個式子裡根本沒有矩陣啊!其實,我麼我們只要稍微使用一點魔法,矩陣就會出現在上面的式子中:

其中「|」符號表示是按列展開的。上面式子實際上就是使用了我們之前所學的數學公式而已。但這個最後的表示式還不是很漂亮,因為還存在加法表示式,即平移變換。我們已經知道了3×3矩陣無法表示平移變換,因此,為了得到乙個更漂亮的結果,我們把上面的式子擴充套件到齊次座標空間中,得

那麼現在你看到mc->p在**了吧,沒錯,

一旦求出來mc->p,mp->c就可以通過求逆矩陣的方式求出來,因為從座標空間c變換到座標空間p與從座標空間p變換到座標空間c是互逆的兩個過程。

可以看出來,變換矩陣mc->p實際上可以通過座標空間c在座標空間p中的原點和座標軸的向量表示構建出來:把3個座標軸依次放入矩陣的前三列,把原點向量放到最後一列,再用0和1填充最後一行即可。

需要注意的是,這裡我們並沒有要求3個座標軸xc、yc和zc是單位向量,事實上,如果存在縮放的話,這三個向量值很可能不是單位向量。

更加令人振奮的是,我們可以利用反向思維,從這個變換矩陣反推來獲取子座標空間的原點和座標軸方向。例如,當我們已知從模型空間到世界空間的乙個4×4的變換矩陣,可以提取它的第一列再進行歸一化後(為了消除縮放的影響)來得到模型空間的x軸在世界空間下的單位向量表示。同樣的方法也可以提取y軸和z軸。我們可以從另乙個角度來理解這個提取過程。因為矩陣mc->p可以把乙個方向向量從座標空間c變換到座標空間p中,那麼,我們只需要用它來變換座標空間c中的x軸(1,0,0,0),即使用矩陣乘法m->p[1 0 0 0]t,得到的結果正是mc->p的第一列。

另乙個有趣的情況是,對方向向量的座標空間變換。我們知道,向量是沒有位置的,因此座標空間的原點變換是可以忽略的。也就是說,我們僅僅平移座標系的原點是不會對向量造成任何影響的。那麼,對向量的座標空間變換就可以使用3×3矩陣來表示,因為我們不需要平移變換。那麼變換矩陣就是:

在shader中,我們常常會看到擷取變換矩陣的前3行前3列來對法線方向、光照方向來進行空間變換,這正是原因所在。

現在,我們再來關注mp->c。我們前面講到,可以通過求mc->p的逆矩陣方式求解出來反向變換mp->c。但有一種情況我們不需要求解逆矩陣就可以得到mp->c,這種情況就是mc->p是乙個正交矩陣。如果它是乙個正交矩陣的話,mc->p的逆矩陣就等於它的轉置矩陣。這意味著我們不需要進行複雜的求逆操作就可以得到反向變換。也就是說,如果我們知道座標空間變換矩陣ma->b是乙個正交矩陣,那麼我們可以提取它的第一列來得到座標空間a的x軸在座標空間b下的表示,還可以提取它的第一行來得到座標空間b的x軸在座標空間a下的表示。反過來,如果我們知道座標空間b的x軸、y軸和z軸(必須是單位向量,否則構建出來的就不是單位矩陣了)在座標空間a下的表示,就可以把它們依次放在矩陣的每一行就可以得到a到b的變換矩陣了。

數電第三章

數位電路使用電壓的時候的特性 在數字離散的使用電壓訊號之中,電壓值分為兩個區域,乙個區域是無效的,兩端的稱為有效區 用到的只是兩端的 邏輯代數,數位電路基礎 數位電路輸出不是任何時刻都有意義的,從真值表的一行跳到另一行,會經過無效區 導線 數位電路中,必備的連線關係,是干擾訊號的 和傳遞,但是不是數...

OpenGl學習第三章

上個星期學習了下金字塔的繪製,然後這週有看了看正方體的繪製,通過依次繪製6個面來繪製正方體,整體 跟上次的金三角沒有區別,只是座標點,顏色,已經繪製的 有點區別,上 看看 這是座標 private static float cubevertexcoords new float new float n...

C Primer Plus 第三章 學習

oop的本質是設計並拓展自己的資料型別,即讓型別與資料匹配。c 內建的型別,分為兩組 基本型別,復合型別。基本型別 整數,浮點數 復合型別 陣列,字串,指標和結構。標識儲存的資料的方法 使用變數 3.1簡單變數 程式必須記錄三個基本屬性 1.資訊將儲存在 2.要儲存什麼值 3.儲存何種型別的資訊 宣...