這段時間閱讀了英文版的NVidia官方的《The Cg Tutorial》,藉此來學習基本的圖形學知識和着色器編程。html
在此作一個閱讀筆記。編程
實現動畫渲染,須要應用程序對時間進行監測,並將它做爲一個全局變量傳遞給着色器。函數
儘可能在GPU上使用頂點着色器執行動畫計算是一種高效的動畫實現方式,它可以釋放CPU,讓CPU處理更多的複雜計算,好比碰撞檢測,人工智能與遊戲玩法。學習
下面是一個如何讓一個對象週期性膨脹變形的例子。這個例子的目標是將時間做爲輸入參數,而後根據時間修改對象幾何體的頂點位置。更確切地說,你須要沿着表面法線移動表面頂點的位置。動畫
根據時間的變化,改變頂點位移Displacement的幅度,就能夠建立一個膨脹或脈衝效果。ui
在上述動畫實現的過程當中,一個重要的過程是計算頂點在法線方向上的位移displacement。你能夠爲displacement選擇一個你喜歡的函數,好比:人工智能
displacement = timespa
也許你不但願物體隨時間無限變大,那麼你能夠選擇使用一個周期函數來計算displacement,好比sin函數:htm
displacement = 0.5 * (sin(time) + 1)對象
此外,你還能夠經過爲displacement增長參數來控膨脹的幅度、頻率,甚至改變膨脹效果:
displacement = scaleFactor * 0.5 * (sin(position.y * frequency * time) + 1)
有時,不一樣於讓頂點在網格中運動,咱們但願把每個頂點都做爲一個獨立的對象,或者稱爲一個粒子。而遵循某種規律運動的粒子的集合被稱爲粒子系統。粒子系統會隨着時間發生變化。
粒子的運動規律可使用一個方程來描述,好比物理中的簡單矢量運動學方程:
pfinal = pinitial + v * t + 0.5 * a * t2
在程序中,經過監測全局時間globaTime並將它做爲統一參數傳遞給頂點着色器,當每一個粒子被建立時,粒子建立的時間被做爲一個變量tInitial傳遞給頂點着色器。爲了知道粒子被激活的時間,你須要使用globaTime減去tInitial:
float t = globaTime - tInitial
再將t代入上一節中的公式:
float4 pFinal = pInitial + vInitial * t + 0.5f * acceleration * t * t
對象空間的位置還須要被轉換到裁剪空間:
oPosition = mul(ModelViewProjectionMatrix, pFinal)
頂點着色器提供了一個名爲PSIZE的輸出語義Semantic用於表示頂點的尺寸,當你將一個點Point渲染到屏幕中時,具備該語義的輸出參數將會決定該點在像素上的寬高。
咱們能夠經過使用點精靈Point Sprites提高粒子的外觀。使用點精靈時,硬件將會把每一個點看成由四個頂點組成矩形來渲染,而不是一個單獨的頂點。點精靈的每一個頂點會被自動分配紋理座標,它容許你經過紋理貼圖改變粒子的外觀。
點精靈可以在不繪製額外三角形的狀況下建立複雜的幾何效果。
關鍵幀這個術語來自卡通動畫。畫家在繪製動畫時,會先勾勒出一個粗糙的幀序列動畫,其中並無包含每一幀的畫面,而只有重要的,也就是「關鍵」的幀。隨後,畫家會補上缺失的幀。有了關鍵幀作參考,這些中間幀會更容易畫。
計算機動畫也使用了相似的技術,3D建模師會爲動畫角色的每一個姿式製做一個關鍵幀。每一個關鍵幀都須要使用相同個數的頂點,且每一個頂點必須互相對應。也就是一個關鍵幀中的頂點必須可以對應到這個模型其餘關鍵幀中相同的點。對於這種關鍵幀模型,遊戲會取模型的兩個關鍵幀,而後將其中每對對應的頂點混合。
關鍵幀插值假定了頂點在每一個關鍵幀中的個數和順序都是相同的,這樣一來就可以保證頂點着色器總可以正確地將頂點進行配對與混合。
插值的方法有不少,常見的兩種是線性插值和二次插值。
經過線性插值,位置會以固定的速率轉。線性插值公式爲:
BlendedPosition = positionA * (1 - f) + position * f
若是想讓轉換速率根據時間變化,能夠採用二次插值,公式爲:
IntermediatePosition = positionA * (1 – f * f) + position * f * f
除了上訴兩種插值公式之外,你還可使用階梯函數、樣條函數或者指數函數進行插值。
當你須要對關鍵幀模型進行照明時,關鍵幀插值就不只涉及到位置的混合,還包括了頂點法線的混合。混合後的法線可能再也不是單位向量,所以此時須要對它進行標準化。
動畫的另外一種實現方式是頂點蒙皮,這項技術也被稱爲「矩陣調色混合「。
不一樣於關鍵幀動畫,頂點蒙皮動畫存儲了模型的一個默認姿式和大量用於旋轉與移動默認姿式的多邊形網格子區域的矩陣,一般,這些矩陣變換被稱爲骨骼Bones。
每一個默認姿式中多邊形網格的頂點都被一個或多個這種矩陣所控制,每一個矩陣都沒指定了一個權重因子,用於指明當前矩陣對頂點的影響程度。假定每一個頂點的全部控制矩陣的權重和爲1。
當你須要渲染擁有頂點蒙皮的模型時,你須要使用每一個頂點的骨骼集合中的全部矩陣對這個頂點執行變換,再將它們按照權重進行混合,獲得的位置就是蒙皮頂點的位置。
當全部的矩陣都是單位矩陣時,模型展示的就是默認姿式——一般是站立面向前方,手腳分開向外伸展。
經過控制矩陣,你可以建立出不同的姿式。3D建模師須要將矩陣和對應的權重分配到模型的默認姿式上,而建立姿式的過程就變成了操做矩陣的過程,而不是控制每一個獨立的頂點。經過這種方式,改變模型的姿式與製做動畫變得很是簡單。
一般,影響一個頂點的矩陣不會超過4個。
對於角色模型來講,最重要的矩陣被用來表明人物身體中骨骼的移動和旋轉,所以頂點蒙皮矩陣被稱爲骨骼。而頂點則表明了皮膚上的點。
同關鍵幀插值動畫同樣,在啓用光照時,頂點蒙皮動畫也須要對法向量進行變換。須要注意的是你須要對每一個法向量只須要使用旋轉縮放矩陣而不是原矩陣進行變換。同時,混合後也須要對法向量進行標準化。
關鍵幀動畫中,每一個姿式都須要不一樣的頂點位置與法向量集合,當角色動做不少時,採用這種方式存儲動畫是很是不明智的。
頂點蒙皮動畫,只須要存儲一個默認姿式的頂點位置與法向量集合以及每一個姿式的矩陣。一般對一個模型來講,由於矩陣的個數遠少於頂點個數,因此使用頂點蒙皮的方式存儲動畫須要的空間遠遠少於關鍵幀動畫。
存儲頂點蒙皮動畫時,每一個頂點還須要額外存儲控制該頂點的矩陣索引,以及相應的權重因子。
頂點蒙皮很是適合用於存儲和回放動做捕捉序列。咱們能夠將每個動做捕捉的幀做爲骨骼矩陣集合存儲起來,並將它應用在擁有相同默認姿式的不一樣模型上。反向運動學求解器Inverse Kinematics Solver也能夠經過生成骨骼矩陣來實現。反向運動學求解器的目的是找到一個能讓一個姿式真實天然地過渡到另外一個姿式的增量骨骼矩陣序列。