渲染管線——光柵化與著色細節
在渲染管線當中,幾何階段完成後,我們得到了處理好的點與點所包含的資訊(螢幕座標,深度資訊,法線資訊,紋理座標,顏色等)
管線在這之前的內容與細節參考:
萊布尼茨的倉鼠:渲染管線綜述萊布尼茨的倉鼠:渲染管線——座標空間變換綜合
光柵化
把傳輸過來收集到的頂點資料收集並
組裝
為簡單的
基本體(點、線、三角面)
,基本上都是三角形面。採用
逐行掃描,遍歷
每一個畫素,檢查是否被一個三角形覆蓋,如果被覆蓋則生成一個
片元(Fragment)
。當片元生成,對其所在三角形頂點的輸入資料(法線、紋理座標、顏色)進行
插值(重心插值法)
,得到該片元所對應的資料值,為後面的片段著色器提供計算資料。
片元並非真正意義上的畫素
,而是包含了多種資訊(螢幕座標,深度資訊,法線,紋理,透明度等)的集合體。
組裝
依靠
索引資訊/快取資訊(VBO, Vertex buffer object)
將點的資料組裝為最基礎的圖形——三角形。由於相鄰三角形會存在頂點共用的情況,尤其在物體網格非常複雜的情況下,冗餘資料會非常多,我們透過使用索引來避免共享頂點間資料的多餘。
索引化三角形:
維護兩張表格,一個三角形表格,一張點表格,每個三角形由點列表的三個索引組成。索引列出的順序決定了面的正反面,逆時針為正。這種方式允許點之間進行共享。
三角形表格:
以三角形為基礎記錄,每個三角形下屬三個點,點之間的位置哪怕重合也不會共享。如果出現位置相同,但是法線或者紋理資訊不同的情況時,不能共享,需要獨立的頂點資料。
遍歷
逐行掃描迴圈進行判斷。
迴圈畫素虛擬碼
如何判斷一個畫素與三角形的關係?這裡畫素採取中心點。
P0P1與P0Q
/
P1P2與P1Q
/
P2P0與P2Q
——三組向量的有一個與另外兩個恰好相反(指向正z或負z)。或者,
QP0
,
QP1
,
QP2
三組向量按順序兩兩叉乘,判斷最後方向是否一致。邊界點可以歸到任意一邊,在圖形API當中如DirectX和OpenGL會有規定,一般實上面和左邊。
但是這樣非0即1的光柵化會造成極為嚴重的
鋸齒/走樣(Aliasing)
現象。
鋸齒與抗鋸齒(Aliasing and Anti-Aliasing)
人眼很難分辨超過300DPI(DPI是“dot per inch”的縮寫。顧名思義,就是指在每英寸長度內的點數。)以上的彩色點。
現實世界場景中的物體是連續的,而2D螢幕空間的畫素點是離散的,當我們使用離散的畫素點來表示連續的物體時,丟失了物體連續的資訊,導致鋸齒的產生。我們從前面光柵化階段已經知道了一個片段是如何產生的,它是抗鋸齒技術的基礎。
在之前的光柵化階段,我們知道每個片段/片元會有一個取樣點,決定一個片元是否被三角形覆蓋方法是看是否覆蓋了取樣點。
濾波抗鋸齒
convolving = filtering = averaging
低通濾波器,去除掉高頻的邊緣訊號
在空間域spatial/時域內,透過卷積進行濾波
轉換到頻域當中,相乘,逆傅立葉變換回空間域,更方便快捷
SSAA( Super-Sampling Anti-Aliasing )
最直接最好的抗鋸齒方法就是SSAA,簡單來說就是提高取樣率,一個畫素不止一個取樣點。拿4xSSAA來說,假設螢幕解析度為400x300,那麼4xSSAA會將渲染出800x600的圖,然後在降取樣到400x300, SSAA可以得到非常好的抗鋸齒效果,對於圖形邊緣與高光都有很高的效果。
不過SSAA需要的開銷是非常大的,光柵化和片段著色器都是原來的4倍,渲染快取的大小也是原來的4倍,並且鋸齒僅在影象中的部分位置會被注意到(邊緣與高光),而對於其他的地方便是過取樣。
MSAA( Multi-Sampling Anti-Aliasing )
MSAA與SSAA原理基本一致,可以理解為是SSAA的最佳化。
SSAA中新的子取樣點(子畫素)完全可以被認為是新的畫素(法線,貼圖等插值都以子取樣點為中心)。由於
光柵化的成本(速度)遠低於片元著色器著色的成本
,所以MSAA在片元著色器處做出了新的最佳化。即:我們依舊會在光柵化時生成新的子畫素(深度),但著色時依舊以大的畫素為基準(原畫素中心位置)只計算一次。
4x示例
光柵化階段,對四個X位置的子畫素執行三角形覆蓋判斷,生成子畫素(深度插值依靠子畫素點)與coverage mask資訊。
畫素著色階段,在畫素中心圓點處執行畫素著色器。該點的深度、法線、紋理座標等資訊由重心插值得到。(若不覆蓋中心,使用子取樣點的重心)(覆蓋的子畫素顏色一致)
對四個子畫素執行模板測試與深度測試,並將測試透過的子畫素資料寫入四倍解析度的模板緩衝與深度緩衝。每個子畫素都擁有自己的深度值。
上圖中左下兩個子畫素通過了深度測試,並且coverage mask為1,因此將顏色寫入到這兩個子畫素對應的顏色緩衝中(依然是每個子畫素一個顏色,共四倍大小)。其他兩個子畫素暫為背景色。
重複上述流程繪製第二個黃色三角形,將畫素著色獲得的黃色複製到右上角的Sample中。
所有繪製結束之後,將四個子畫素的顏色混合獲得最終輸出的畫素顏色。
MSAA流程中所使用的所有緩衝區都變成了原來的四倍大小,這也是為什麼MSAA增加了非常多的視訊記憶體和頻寬消耗,但在片元著色器部分加快了速度。MSAA可以很好地處理圖形邊緣的鋸齒,但由於顏色只計算一次難以處理高光鋸齒。
MSAA與延遲渲染(Deferred Rendering)
顯然
不相容。MSAA已經被大多數硬體整合實現,延遲渲染中第一步後生成的G-Buffer不進行光照著色,且已經丟失了幾何資訊無法生成子畫素,而MSAA對著色是有抗鋸齒效果的;
即使強行使用MSAA,由於G-buffer的存在,記憶體和頻寬會爆炸的。
最新的API版本似乎又支援了,但是主流引擎中截至UE4。26,在選擇延遲渲染之後,依舊只支援FXAA跟TXAA。
著色頻率(Shading Frequency)
平面著色(Flat shading)
:每個多邊形應用一個顏色,對於每個三角形片元,僅評估一次光照(採用索引的第一個頂點,有時也可以用面法線),顏色資訊在頂點著色器便已經計算完成。通常在其他物體著色成本已經很高時使用,看起來很差,但是這個很適合風格化的渲染。
高洛德著色(Gouraud shading)
:高洛德著色就是在頂點著色器中計算頂點的光照資訊,所以也叫作逐頂點著色。該方法會在頂點著色器中計算三個頂點的光照資訊即顏色,然後在光柵化階段插值得到三角形內部各個片段的光照資訊。
馮氏著色(Phong shading)
:不是那個光照模型,這裡是著色頻率。馮氏著色也被稱為逐片段著色。馮氏著色是三種著色方式中效果最好的,也是效能消耗最大的著色方式。馮氏著色會在根據輸入的頂點法線資訊在三角形遍歷生成片元階段插值得到各個片元的法線資訊,然後在片段著色器中利用法線、紋理座標、位置等資訊計算每個片段的光照資訊。
頂點法線:
法線很容易理解,即垂直於切線的向量,面法線自然就是垂直於面。那頂點法線又從何而來呢,嚴格的從法線的定義上來說,其實頂點是不存在法線的,我們無法尋找到頂點處的切線,那為何又有頂點法線這個概念的?讓頂點也擁有法線,是為了在光照計算時,能夠在多面體的表面獲得一種平滑的效果,也就是上述第三種著色頻率。
頂點法線可以依據製作者的需求在DCC來設定
:1。使索引中第一個點等於改面的法線;2。根據共享該點的各個面的面法線加權平均出點法線,權重自己設定。
如果頂點的法線與所在面的法線一致,多個面共享一個頂點的話,則會匯出多個頂點,頂點位置一致,法線不同。
想要獲得平滑的效果必須phong(平滑)著色的同時,物體設定為軟邊(光滑組)。
目前主流的法線計算方法是使用法線貼圖來提供法線片段的資訊。
著色頻率並非越高越好,應用中普遍採取的是Phong著色頻率,同時距相機較遠的話會採用其他頻率。
紋理貼圖(Texture Mapping)
紋理對映是一種定義3D模型高頻資訊、表面紋理、顏色資訊的方法。早期的貼圖僅指漫反射貼圖,之後更多的紋理技術被應用進來,多紋理技術(Multitexturing),紋理濾波(Texture filtering), mipmaps,烘培(Baking), 法線貼圖,高光貼圖,環境光遮蔽貼圖,高度圖,置換貼圖等等。這些技術極大地減少了面數和光照條件降低了計算,是最佳化渲染不可繞開的一部分,使得在實時渲染中實現更好的效果成為了可能。
我們將貼圖上的每個畫素成為紋素(texel,紋理畫素texture pixel的意思,用於和畫素進行區分),紋理對映其實就是進行紋素和畫素對應的過程,紋理濾波技術和mipmaps便是為了解決該問題。
重心插值
紋理對映依靠儲存在點中的資訊,該資訊定義了頂點在紋理中對應的位置。三角形內的點依靠插值獲得資訊即三角形內任意一點可以寫成如下形式的表示:
求出α、β,γ的值,依靠權重,便可進行插值,求值結果如下:
光照模型(illumination model)/著色模型(Shading model)
光照模型即根據物體表面方向、視角方向和照明等因素的變化以描述物件顏色的模型。
我們所瞭解學習到的
Lambert,Phong,Blinn-Phong
等都是著色模型,而
材質
是一個光照模型下經過其不同屬性的調節獲得不同的效果。例如:Blinn-Phong是一個光照模型,從總的方面規定了材質與光互動的規則和操作者可以調節的屬性如環境光,高光顏色區域等。操作者可以使用這個模型透過調整所所給予的屬性獲得不同的材質,如使用Blinn-Phong模型實現類似木頭和金屬等材質的效果。
著色模型的計算階段在片元著色器。
Blinn-Phong模型,l光線方向,h半程向量,點光源考慮衰減
Blinn-Phong模型specualr部分n的含義
上一篇:減肥早餐應該吃什麼?
下一篇:網頁頁碼為什麼要下一頁和上一頁?