WebGL 是以 OpenGL ES 2.0 為基礎的 3D 編程應用接口。
渲染管線(圖形流水線)
渲染管線是指將數據從3D場景轉換成2D圖像,最終在屏幕上顯示出來的總過程。它分為幾個階段:應用階段、幾何階段和光柵階段,關於這3個階段的詳細介紹可以點這里查看。
下面我們來仔細看看 WebGL 中的每個步驟:
1.頂點着色器
頂點着色器一般用來對模型的頂點進行矩陣變換,一般就是將模型的所有頂點乘於一個變換矩陣,使該模型位於相對於WebGL坐標系中的某個位置。
頂點着色器是可編程的,使用的語言是 GLSL 來進行編寫,下面我們主要說一下幾種常用的屬性類型:
- attribute變量:用戶自定義變量,一般是存儲頂點屬性的變量;
- uniform變量:恆值變量,一般表示每個頂點都一致的變量,比如變換矩陣、光照等;
- varying變量:易變變量,將頂點着色器的數據傳遞給片段着色器時使用;
- 內置常量:WebGL 內部的常量;
2.圖元裝配
這個階段,GPU會將我們傳入的頂點裝配成三角形、線段或者點;裝配好之后,會自動截去不在可視區域內的信息;
3.光柵化
這個階段,GPU會將裝配好的三角形轉換成對應的像素,並將這些像素傳入下一個階段;
4.片段着色器
得到光柵化的片段像素位置數據之后,就可以通過片段着色器為這些像素進行上色了,這是第二個可以編程的地方;
我們可以對圖片進行采樣之后,再這里進行上色;
5.逐片段操作
本步驟包含了多個子操作,每個操作都會影響當前片段最終的顯示效果,下面我們看下幾個常見的子操作:
1.裁剪測試
會有一個裁剪的范圍,如果像素位於該范圍之外,會被剔除,不會到達繪制緩存;
2.多重采樣片段操作
這一步會修改像素的alpha值和覆蓋值,主要用來實現抗鋸齒的效果;
3.背面剔除
剔除是一種通過避免渲染背對觀察者的幾何體面來提高性能的優化措施,比如一個立方體,你不會看到背離你的那一面(總是只有一面在你的前方),因此我們不需要繪制出背面;
4.alpha測試
指的是將一個像素點的alpha值和一個固定值比較,如果比較的結果失敗,像素將不會被寫到顯示輸出中;
5.模板測試
模板緩存與顏色緩存的大小一致,模板緩存中的像素點與后台緩存的像素點是一一對應的。
模板緩存允許我們動態地、有針對性地決定是否將某個像素寫入后台緩存中。模板緩存用與獲得某種特效,如鏡面效果或陰影效果。在實現鏡面效果時,我們在“鏡子”這塊區域中繪制某個特定物體的映像,而使用模板緩存來阻止物體映像在“非鏡子”的區域中進行繪制;
為了進行這種阻止,就需要使用模板測試。判斷是否將某個像素寫入后台緩存的決策過程,稱為模板測試;
6.alpha融合
融合技術能使我們將當前要進行的光柵化的像素的顏色與先前已經光柵化並處於同一位置的像素的顏色進行合成,即將正在處理的圖元顏色值與存儲中后台緩存中的像素顏色值進行合成。利用該技術,我們可以獲得各種各樣的效果,尤其是透明效果。不過值得注意的是,為了場景中繪制透明物體,通常需要對物體按照由后到前的順序進行混合處理,如果按照任意順序進行處理將會產生嚴重的失真。所以在blending(混色)操作之前要來一次深度測試;
7.深度測試
這一步會進行深度測試,拋棄掉位置靠后的像素值,因為這個位置的像素本身就是被更前面的像素覆蓋的;
8.融合
這一步會將新的顏色值和已經存在的顏色值進行組合,得出融合后的顏色值,比如,老的顏色是紅色,新的是50%透明的黑色,那么融合之后的顏色看起來就應該是暗紅色;
5.抖動(Dithering)
這一步是為了解決可使用的顏色過少會出現色帶的問題,通過較少的顏色來模擬較多顏色的技術,可以查看這篇文章來理解;
幀緩存
數據經過整個渲染管線處理之后,最終會寫入到幀緩存中,幀緩存存儲了最終會顯示到屏幕上的顏色數據。
幀緩存包含了 3 個具體的緩存:
1.顏色緩存
存儲每個像素點的具體顏色值的緩存,常見的具體格式可以分為:
- 16位:RGB565,紅色5位,綠色6位,藍色5位,不保存透明通道(之所以綠色多1位是因為人眼對綠色更加敏感);
- 24位:RGB888,紅色8位,綠色8位,藍色8位,不保存透明通道;
- 32位:RGBA8888,紅色8位,綠色8位,藍色8位,透明通道8位;
2.Z-緩存(深度緩存)
存儲每個像素點的深度,用來決定是丟棄當前像素顏色還是保留,假設,新渲染的顏色在舊顏色的前面,那么就覆蓋舊顏色,如果新顏色在舊顏色的后面(被遮擋了)則保留舊顏色。
3.模板緩存
用來控制顏色緩存某個位置的寫入操作,常用來處理陰影。