1. 程式人生 > >Unity Shader數學基礎

Unity Shader數學基礎

本系列文章由Aimar_Johnny編寫,歡迎轉載,轉載請標明出處,謝謝。

http://blog.csdn.net/lzhq1982/article/details/73523986

說實話,我覺得書上數學基礎這章是整本書最難的章節,有很多數學不好的人可能大概看看甚至會直接跳過去,這樣不好,畢竟shader的各種運算原理離不開數學,明白數學原理會使你對shader的學習事半功倍,所以花時間也要啃下來,其實不難,用心就好,我會分兩篇來記錄數學基礎,本篇講數學知識部分,下篇講空間變換的矩陣運算部分。

1、笛卡爾座標系

上學的時候我們都學過二維座標系,其實就是二維笛卡爾座標系,所以沒啥好說的,只是有一點要注意,OpenGL也就是Unity預設的座標系是以左下角為原點,DirectX是以左上角為原點。如下圖:

我們重點要面對的是三維笛卡爾座標系,如下圖:

3個座標軸被稱為該座標系的基向量,3個座標軸互相垂直,長度為1,這樣的基向量被稱為標準正交基,如果長度不為1,被稱為正交基。當然,座標軸方向也不是固定的,涉及到z軸向裡為正還是向外為正,也就有了大家熟知的左手座標系和右手座標系。

雖然對開發者來說,左手和右手座標系沒有優劣之分,但我們要清楚當前平臺的座標系準則,不然空間運算就可能是錯的,OpenGL是右手座標系,DirectX是左手座標系,而對於Unity,模型空間和世界空間是左手座標系,向裡為z軸正向,而觀察空間,也就是以攝像機為原點的空間,用的是右手座標系,攝像機前向是z軸負方向,注意觀察空間是看不到的,只有計算中才能遇到。

2、點和向量

點(point)是一個位置,沒有大小的概念。二維座標P = (X, Y),三維座標P = (X, Y, Z)。

向量(vector),也被稱為向量,是空間中包含了模(magnitude)和方向(direction)的有向線段,比如速度。與之相對的是標量,只有模,沒有方向,比如距離。

向量的運算,假設向量v = (x, y, z),各種運算如下:

1)向量和標量的乘除

2)向量的加減

它們的幾何意義如圖:

3)向量的模

4)單位向量

很多情況下,我們只關心向量的方向而不是模。比如光照模型中,往往需要知道法線方向和光源方向,這種情況下我們不關心向量有多長,這樣就需要計算單位向量。單位向量指的是模為1的向量,也被稱為被歸一化的向量(normalized vector),而把非零向量轉換為單位向量的過程被稱為歸一化。計算單位向量公式如下:

5)向量的點積

程式碼中用dot(a, b)來表示。

點積的幾何意義

點積幾乎用到了圖形學的各個方面,其中一個就是投影。有一個單位向量a和長度不限的向量b。那麼a與b的點積就是b在a方向上的有符號的投影。投影的結果是有符號的,如下圖:

如果a不是單位向量,那麼a與b的點積等同於b在a上的投影,再乘以a的長度。

點積的幾種數學公式:

下面要重點介紹點積的另一種表示式:

推導很容易,這裡不加介紹。從這個公式可以看出兩個向量的夾角對於點積結果的影響,小於90度為正,等於90度為0,大於90度為負。還可以用反餘弦求出兩個向量的夾角。

6)向量的叉積

相信上學時都學過,這裡直接上公式:

注意:

叉積的幾何意義:

兩個向量叉積會得到一個同時垂直於這兩個向量的新向量

我們知道兩個方向互不平行的向量可以確定一個平面,所以叉積最常見的應用就是計算垂直於一個平面的向量,我們後面會在頂點法線,切線那裡用到。

3、矩陣

如果還沒把上學學的東西都還給老師的話,就跟我回憶一下吧。

向量可以看成是nx1的列矩陣或1xn的行矩陣,其中n對應了向量的維度。把向量和矩陣聯絡在一起是為了讓向量像矩陣一樣一起參與矩陣運算。這在空間變換中非常有用。

1)矩陣的運算

矩陣和標量的乘法:

矩陣和矩陣的乘法:

假設矩陣A的大小是4x2,B的大小是2x4,計算C = A x B,則C的大小是4x4。

其中:

也就是對應的行乘以對應的列。

矩陣乘法的一些表示式:

2)特殊矩陣

a、方塊矩陣

簡稱方陣,就是行和列相等的矩陣。如果在方陣中除了對角線上的元素其他元素都是0,則成為對角矩陣。

b、單位矩陣

對角線元素都是1的對角矩陣就是單位矩陣。用 I 來表示。例如3x3的單位矩陣如下:

MI = IM = M

c、轉置矩陣

d、逆矩陣

不是所有的矩陣都有逆矩陣,比如零矩陣,首先該矩陣必須是個方陣。M的逆矩陣表示為,它們滿足一個公式:

如果一個矩陣有逆矩陣,我們就說它是可逆的或者非奇異的,相反則是不可逆的或奇異的。

逆矩陣的公式:

這裡有個逆矩陣的幾何意義,矩陣是可以表示變換的,逆矩陣則可以還原這個變換。比如用矩陣M對向量v進行了一次變換,如果我們想還原回v,只需要對變換結果乘以M的逆矩陣,公式如下:

f、正交矩陣

如果矩陣M和它的轉置矩陣的乘積是單位矩陣的話,矩陣M就是正交的,公式為:

所以和上面的逆矩陣相比,我們發現:

這個公式很有用,因為求解一個矩陣的逆矩陣計算量很大,但轉置矩陣很容易,所以如果我們知道該矩陣是正交矩陣,那用轉置矩陣就可以當逆矩陣了。那如何判斷一個矩陣是正交矩陣呢。用計算公式求解當然可以,但同樣很麻煩,讓我們看看它的幾何意義。根據正交矩陣的定義,我們有:

我們可以把()當成M每一行和M轉置每一列的向量,所以就有了等式:

我們從上面的等式中發現了些規律:

一、和自己點積的時候都為1,還記得向量和自己點積等於其模的平方的公式吧,不記得就再看看上面,模的平方為1,那模就是1,所以它們都是單位矩陣。

二、它們之間兩兩點積都得0,說明它們互相都垂直。

而這兩個規律對每一列同樣適用,因為M是正交矩陣,其轉置也是正交矩陣。這兩個規律說明什麼,又是單位向量,又是彼此垂直,這不就是我上面提到的標準正交基嗎。所以我們得出結論,正交矩陣的行與行之間,列與列之間分別構成了一組標準正交基。

這在空間轉換中很有用,如果這些基向量是一組標準正交基的話,那我們就可以直接用其轉置矩陣來得到其逆矩陣了。

3)行矩陣還是列矩陣

我們都知道,向量是可以作為行矩陣或列矩陣的,本身沒有區別,但和矩陣相乘就有區別了,因為我們要用到各種空間轉換會用到向量與矩陣相乘。比如v代表的1x3的向量和M代表的3x3的矩陣相乘,如果vM那結果是1x3的矩陣,如果Mv(v變成列矩陣),那結果就是3x3的矩陣。我們往往需要的是後者,所以在Unity中,常規做法是把向量放在矩陣的右邊,即Mv。例如:

CBAv = (C(B(Av)))

表示先對v使用A變換,再用B變換,再用C變換,是從右往左的順序。所以如無特殊情況,我們往往使用向量的列矩陣表示式。 ---------------------  作者:Aimar_Johnny  來源:CSDN  原文:https://blog.csdn.net/lzhq1982/article/details/73523986?utm_source=copy  版權宣告:本文為博主原創文章,轉載請附上博文連結!