作者:心動前端工程師 山楂
山楂最近入坑計算機圖形學,在心動內部做了一次分享,分享內容主要基於閆令琪的課程。下面是這次內部分享的筆記,請配此 slide 食用。
計算機圖形學在遊戲、電影、設計、VR & AR、視覺化、模擬、GUI、字型等領域得到廣泛應用,包括光柵化(rasterization)、幾何(curves & meshes)、光線追蹤(ray tracing)、動畫模擬(animation/simulation)等內容。其中,光柵化可以說是計算機圖形學中最為基礎的概念。簡單來說,光柵化是將三維場景對映成平面圖形,再將圖形分解成多邊形,多邊形打碎成畫素,顯示到螢幕上的過程。
光柵化涉及的數學知識主要是線性代數,包括向量(求和、點積、叉積)和矩陣(乘積、轉置、單位矩陣)等。光柵化涉及的大量變換都可以表達為向量和矩陣的運算。
縮放、切變、翻轉、旋轉這些線性變換可以用矩陣乘法表示,引入齊次座標後,平移也同樣可以像線性變換一樣用矩陣乘法處理。包含俯仰、偏航、滾轉的三維複雜旋轉,可以用羅德里格斯旋轉方程描述。
縮放、旋轉、平移等基本的變換操作發生在模型變換(modeling tranformation)階段,類似拍照過程中的找景、模特就位。模型變換之後是相機變換(view tranformation)階段,在這一階段我們確定相機和物體的相對位置,類似拍照過程中的找角度、放相機。具體來說,我們通過相機的位置、看向的方向、往上的方向來表示相機,然後為了簡化計算,將相機和物體一起移動,在保持兩者相對位置不變的前提下將相機移動至座標系原點。下一階段是投影變換(projection tranformation),類似拍照過程中的按快門。投影主要分為正交投影和透視投影兩種。正交投影相對簡單,光線平行,各點的相對位置不變,將場景平移縮放至 [-1, 1]^3
的標準立方體上,再去除 Z 值壓到平面上。這裡,縮放至標準立方體是為了簡化計算。透視投影,近大遠小,類似人眼觀看物體的方式。運用近平面通過擠壓不會發生變化、遠平面通過擠壓 Z 值不會發生變化、中心點通過擠壓也不會發生變化三點性質,可以實現透視投影。這三個階段組成了檢視變換。最後還有一個視口變換(viewport transformation),將之前縮放至標準大小的場景根據螢幕的長寬再進行一次變換,投射到螢幕上。
光柵化分解圖形為多邊形,其中運用最廣泛的是三角形,因為三角形內部是平面,內外定義很清晰,內部任意一個點都可以插值漸變。三角形輸出到螢幕時,會遍歷螢幕上的每個畫素,通過向量的叉乘判斷畫素點是否在三角形內。當然,實際計算時會使用包圍盒簡化計算,包圍盒外的畫素點就不用再進行向量叉乘運算了。為了應對鋸齒、摩爾紋等取樣瑕疵,可以先模糊再取樣。雖然對每個畫素進行卷積操作可以實現模糊,但計算量比較大,所以一般使用超取樣,每個畫素內部增加取樣點再進行平均。
利用 Z 值可以處理遮擋的問題,維護一個 Z-Buffer 記錄影素點的深度,如果三角形面上的畫素點 Z 值小於 Z-Buffer 中的值,那就更新 Z-Buffer 中的值為當前 Z 值,同時更新該畫素點的顏色為當前三角形面上的畫素點的顏色。
再接下來要處理的是著色(shading)問題,因為物體的顏色會受光照影響,更復雜的是,不同的材質和光線的相互作用不同。最基礎的著色模型是Blinn-Phong反射模型,它從高光、漫反射、環境光三個維度去綜合考慮著色。漫反射主要考慮材質的漫反射係數、光線強度、光源遠近、入射方向和材質表面的夾角大小。不同的著色頻率會產生不同的顯示效果,有逐平面法線(flat shading)、逐頂點法線(gouraud shading)、逐畫素法線(phong shading)三種。逐平面法線以三角形面為著色單位,計算很快,但效果較差。將共享一個頂點的所有三角形面的法線向量相加求均值,可以得到頂點的法線向量,據此可以對每個頂點進行著色,然後直接插值計算三角形面內每個點的顏色,這就是 gouraud shading。如果不直接插值計算三角形內每個點的顏色,而是直接光柵化後形成畫素點,再據此對每一個點著色,就是 phong shading。
計算機圖形中常常提到的渲染管線通常可分為頂點處理、三角形處理、光柵化、片元處理、幀緩衝處理,其實具體來說大致就是上面提到的這些內容。頂點處理就是對所有頂點資料進行檢視變換,三角形處理就是這些頂點組合成各三角形面(三角面剖分),然後是光柵化判斷畫素點是否在三角形內,再接下來是片元處理,對每個片元進行著色,最後則是整合所有資訊輸出至螢幕。其中,片元處理除了之前提到的著色外,也可以進行紋理對映,用紋理貼圖代替顏色。
最後推薦兩個超棒的視訊教程:
- 3Blue1Brown 的 線性代數的本質,以視覺化的方式來理解線性代數(總時長:2h40m)。
- 閆令琪的 現代計算機圖形學入門,全程無一句廢話,通俗易懂,詼諧幽默(總時長:28h+)。