劍英陪你玩轉圖形學 (三)歸去來

瘋光無線發表於2014-09-18

今天的主題是數學,尤其是要把向量說一說

開篇廢話

王全安又進去了,最近不太好引用島國文化來開篇,來點民族的。

恰逢中秋,讓我想起了一首膾炙人口的水調歌頭。

 

明月幾時有,把酒問群友。
不知這次版本,今晚能出否。
我欲推倒重構,又恐專案經理,深夜對我吼。
增刪改程式碼,好像沒儲存…..

深呼吸,看螢幕,淚在流。
不應有恨,誰沒忘記存程式碼?
人有悲歡離合,碼有丟失衝突,此事古難全。
但願人長久,leader別發現。

 

小夥伴們中秋都是怎麼過的?有沒有專案經理深吼你呢?

歡迎來德雲社聽相聲,哦不,來聽李總講故事,好像也不對,我們是一個玩程式碼系列,圖形學方向。

 

圖形學是個綜合學科,他的很大一部分都是3D數學。

圖形學用的3D數學,客戶端邏輯用的3D數學,有什麼不一樣的?

我不知道分界線在哪裡,我只知道做遊戲客戶端,3D數學無處不在。

既然躲不開,就讓我們來好好享受一番吧。

快速提高班

現在,教大家一些快速提高自己業務(zhuangbi)水平的方法。

今天講提高業務水平的最後一個要訣,悟。

悟是你一定要鑽研出一些你自己的觀點。百度搜不到的東西。

這樣和別人交流業務的時候,可以極大的提高別人對你的印象。

忍、持、悟。這次已經把全套祕籍都教給你了,讓我們來回顧一下。

忍:不要主動去教別人,別人有疑惑會找你,主動去教容易招致反感。

持:要有選擇的回答,拿不準的東西不要亂答,提升準確性。

悟:要有自己的觀點。

學會這一套,業務(zhuangbi)水平就會一發不可收拾。

 

現在給大家簡單的介紹一下Unity3D的數學庫,對提升業務水平有幫助哦。

基本數學工具:

UnityEngine.Mathf

集中了float型數值計算的相關數學函式的靜態型別,比如cos sin sqlr

相對System.Math 更加實用,因為我們最長使用的資料型別是float,Mathf會更方便。

UnityEngine.Random

隨機數產生器,和System.Random 使用方法不同,原理一樣,只是靜態化了,可以少寫兩行。

特定的數學工具:

特定的數學工具對應的數學函式就在這個型別內

Vector2 Vector3 Vector4

表示向量或者頂點,他們的相關計算函式都在Vector2 Vector3 Vector4內。

比如Vector3.Cross 叉積 Vector3.Dot 點積

Rect

表示一個2D矩形區域

Bounds

表示一個3D的方塊區域

Matrix4X4

表示矩陣,矩陣用土的掉渣的方式表示一個空間變換,旋轉跳躍我眯著眼。

Quaternion

表示四元數,四元數用土的掉渣的方式表示一個旋轉,這個我們文後會介紹。

常用的數學工具就這些,當然還有float,這個我們最最常用的數學工具。

理解計算的意義

說到數學,對很多人來說是幫助睡眠小助手。

睡前兩行數學書,包你一夜好睡眠。

確實對著那些名詞,是會讓人混混欲睡的。

現在開始上圖片。

上錯圖了,不好意思

阿基米德說:給我一個支點,我就能撬動地球

卡馬克說:給我一個畫素,我就能弄一個3D引擎

李總說:……….

偉人們告訴我們,要學真東西就得從零單排。

我準備了一組例子

下文所提的例子可以線上使用
http://lightszero.github.io/basemath/outweb.html
例子程式碼可以從如下GITHUB地址取得
https://github.com/lightszero/BlockFun/tree/master/unity/basemath

隨機數有什麼用

隨機對應固定,產生更多自然的變化。但是隨機數也是受控的,這是概率論方面的問題了,

我們準備了兩個例子,一個是用隨機數來求圓周率


可以用隨機數來求圓周率

隨機在貼圖上畫點,把圓內和圓外的分別統計出來,可知圓的面積是0.5*0.5*PI,正方形的面積是1*1.

則PI = 圓的面積/方的面積*4.

畫的總點數可以認為是方的面積

落在圓內的點數可以認為是圓的面積

另一個是用隨機數來分佈角色


圖中一螢幕的蒼老師,是用隨機數來分佈的,你每次開啟都會不一樣。

向量

向量是本篇的重點

Vector3是一個資料結構,既可以表示標量點,也可以表示一個向量。

你希望他是什麼他就是什麼,這也是很多小夥伴困惑的地方。

這其實是我們在程式設計中只關心數值所產生的一個普遍問題。

想想float,單位和功能並不在其中。

表達縮放,float可以,表達速度,float 可以,表達長度,float可以,表達時間,float可以。

賦予資料結構何等意義,是人類該考慮的問題。

 

對於座標的加減法,這些自不必提,我們來釐清一下點積和叉積這兩個非常重要的運算。

 

向量點積的意義:

還記得盟軍敢死隊把敵軍的視野標識出來誕生的玩法麼?判斷我們的豬腳是否暴露在敵人的圓錐形視野中,就要依靠點積。

點積的意義主要在於求出兩個向量的夾角,試想一下,夾角和視野的關係。

在shader的光照模型中,用三角面的法線和光線方向確定光強,用向量求夾角,這就是點積的意義。

關於點積我們準備了一個例子

一螢幕的蒼老師,滑鼠的位置表示紅音老師的目光方向。
紅音老師的目光範圍是左右30度。
紅音老師目光所及的位置蒼老師是白色的,看不到的位置蒼老師是紅色的。

 

向量叉積的意義:

如果你有一隊飛機,在飛行過程中想讓他們保持隊形,向量叉積的計算就剛好可以滿足你,叉積求出和兩個向量垂直的向量。

利用這個特性可以隨時計算出隊長的前後左右上下正方向,當然也可以按別的什麼東西對齊。

在直接繪圖相關的計算中,叉積的一大應用是自動計演算法線。與一個三角面的任意兩邊垂直的向量一定與這個三角面垂直,就是這個三角面的法線。

關於叉積我們也準備了一個例子

無論紅音老師看向哪個方向,紅音軍團總會保持陣型屹立在紅音老師的周圍

 

插插插

插值,可以說是客戶端開發中最主要的思想。

是動畫的基礎思想,對Vector3來說,插值有著兩種截然不同的意義。

因為Vector3同時表達兩種意義,作為標量他表示3D空間中的一點。

對點和點的座標插值,就是兩點間的一條直線。

延既定路線運動,基本都是對點的插值而來

 

作為向量Vector3表達一個方向,對方向和方向插值,就是一個旋轉扇面。

比如經典的小蛤蟆,他的臉是你指哪裡就轉向哪裡

但是作為向量時直接使用Vector3插值,會得到奇異的結果。

如圖,從方向A插值到方向B,直接用Vector插值,會導致中間值的長度改變,在AB180度時,再想想這個奇異的結果。

對向量的插值,就要依靠四元數這個工具了,後文我們會順便提一下。

向量的插值和頂點的插值,在直接繪圖的計算中,有一個很典型的場合,骨骼動畫。

 

我們也準備了一個插值的例子
在上面的基礎上改為紅音老師滑鼠點選後才轉向。
會通過插值逐漸轉向
但是紅音軍團為了快速完成保衛任務,採用直線移動,最後會保持陣型不變。
紅音軍團通過座標插值移動。

本篇講到這裡就結束了,再會。後面捎帶介紹一下其他的數學工具。

向量弄清楚了,都不是問題。

矩陣

記得麼,我們曾介紹過,矩陣是一個土的掉渣的數學工具

矩陣的意義是一個空間變換:旋轉、跳躍、我眯著眼。

矩陣可以描述任何一種空間變換。大約有旋轉、平移、縮放這些資訊。

雖然矩陣,也可以描述出梯形變換和平行四邊形推倒的效果,並不常用。

一個3*4矩陣內部儲存了旋轉、平移、縮放的引數。

可以儲存一個矩陣,描述一個物體在另一個空間中的位置。

插插插

遺憾的是,矩陣並不適合於插值。

僅有平移可以直接插值。

矩陣和Vector一樣,對於旋轉直接數學插值會產生奇異結果。

對於縮放,矩陣也會產生一個不明顯的錯誤。

如果模型進行xy軸不均勻的縮放,那麼同一個矩陣並不適合這個模型的法線,會導致法線和表面不再垂直。

這也是為什麼光照模型中要使用逆轉置矩陣的原因。

四元數

四元數也是一個土的掉渣的描述工具,他描述的資訊叫做軸角對。

軸角對,就是一個旋轉軸,加一個旋轉角度。

設軸向量為n,旋轉角度為t
四元數的值為:
x = n.x * sin(t / 2)  
y = n.y * sin(t / 2)  
z = n.z * sin(t / 2)  
w = cos(t / 2)

至於超複數那套解釋,知道一下用於提升業務(zhuangbi)水平就行了。

其實四元數這麼存,只是為了四元數乘法直接得到兩個旋轉連線後得到的新的軸角對。

四元數這樣儲存,可以讓四元數乘法直接變成旋轉連線工具。

紅色的q1表示一個旋轉,綠色的q2表示一個旋轉,他們的乘法結果就是藍色的q3。

四元數表達的資訊是一個旋轉變換,可以直接存一個四元數作為物體的旋轉量。

 

另外插入一點個人的意見,也許滿是無知與偏見,聽一下就行了:

四元數發明於1843年,圖形學誕生於1963年,可是1985年四元數才被用於表達旋轉並逐漸推廣。

用於圖形學中的四元數,最重要的價值就是軸角對的一種計算工具。

我對超複數、非零四元數乘法環共軛作用實現轉動那套並不信服,就像是馬後炮一樣。

如早認識到非零四元數乘法環共軛作用實現轉動,又怎麼會花了二十幾年才找到一個表達旋轉的適合方法。

插插插

四元數對於旋轉的描述就是旋轉軸+角度,沒有比他更適更針對旋轉插值的了。

骨骼動畫中對於骨骼旋轉的插值計算,都是使用四元數插值的。

區域

區域就是包圍盒

有兩種常用的形式

Axis Aligned Bounding Box

oriented bounding box

AABB 軸對齊包圍盒。

OBB 定向包圍盒。

是為了簡化碰撞和包圍測試的一種方法。將一堆東西包在一個盒子裡

我找到一張圖,說明的很形象,把小人包起來,判斷小人在不在一個區域,判斷他的盒子就快的多。

OBB是小人在自己空間中的盒子,他不隨小人的旋轉跳躍而變化。

AABB是小人在世界空間中的盒子,小人旋轉就要重新生成。

除了碰撞盒,還有其他常用的包圍形式

2D的Rect

3D的OBB AABB 還有碰撞球,膠囊體等等。

 

全文完。順便爆照

a

相關文章