渲染管线简介
轉(zhuǎn)載自:?https://blog.csdn.net/nikoong/article/details/79776873
渲染管線入門
?
渲染管線中一些技術(shù)名詞大部分是英文直譯,光看中文很容易被誤導(dǎo)。所以我們必須在了解一個(gè)技術(shù)的具體作用之后,才能了解它到底是什么。這篇博客我主要翻譯自Minh Tri Do Dinh的GPUs - Graphics Processing Units一文。也就是一些論壇里推薦給新手閱讀的圖形處理器架構(gòu)(GPU_Architecture)與圖形管線(Graphics_Pipeline)。在此之上我還添加一些注解,方便大家閱讀。
基礎(chǔ)名詞
-
3D物體:任何物體,其幾何形狀都是由三角形組成的。三角形,或者任何圖形,都由頂點(diǎn)組成。?
? -
頂點(diǎn):具有空間坐標(biāo)和其他信息(如顏色和紋理坐標(biāo))的點(diǎn)
-
紋理:映射到3D物體表面的圖像,這會(huì)造成該物體由某種材料組成的幻覺(jué)。物體的頂點(diǎn)存儲(chǔ)著紋理坐標(biāo)(2維向量),用于指定紋理如何映射到任何給定表面。?
? -
齊次坐標(biāo):3D空間中的點(diǎn)通常需要3個(gè)坐標(biāo)來(lái)指定位置。如果繼續(xù)用3個(gè)坐標(biāo)表示,有時(shí)會(huì)遇到問(wèn)題。例如:頂點(diǎn)平移時(shí)的操作是加一個(gè)向量,頂點(diǎn)旋轉(zhuǎn)時(shí)的操作是乘以3x3矩陣)。所以我們通過(guò)擴(kuò)展三維向量來(lái)繞開(kāi)這個(gè)問(wèn)題。我們添加另一個(gè)坐標(biāo)(w坐標(biāo),從而得到所謂的齊次坐標(biāo)[注1]。這樣一來(lái),頂點(diǎn)的所有變換都可以通過(guò)將其四維坐標(biāo)與特定的4x4矩陣相乘來(lái)進(jìn)行,使得計(jì)算更容易。齊次坐標(biāo)的另一個(gè)用途是明確區(qū)分向量和點(diǎn)。
渲染管線
渲染管線(Graphics pipeline/rendering pipeline),其實(shí)貼切的翻譯應(yīng)該是渲染流水線。渲染流水線就是將數(shù)據(jù)從3D場(chǎng)景轉(zhuǎn)換成2D圖像,最終在屏幕上顯示出來(lái)的總過(guò)程。它分為幾個(gè)階段:應(yīng)用階段、幾何階段和光柵階段。?
應(yīng)用階段:主要是CPU與內(nèi)存打交道,例如碰撞檢測(cè),計(jì)算好的數(shù)據(jù)(頂點(diǎn)坐標(biāo)、法向量、紋理坐標(biāo)、紋理)就會(huì)通過(guò)數(shù)據(jù)總線傳給圖形硬件 。?
幾何階段(Geometry Stage)
這個(gè)階段也被稱為“變換和光照”階段。為了從3D場(chǎng)景轉(zhuǎn)換到2D,場(chǎng)景中的所有物體都需要轉(zhuǎn)換到幾個(gè)空間。每個(gè)空間都有自己的坐標(biāo)系。這些轉(zhuǎn)換是通過(guò)一個(gè)空間的頂點(diǎn)轉(zhuǎn)換到另一個(gè)空間的頂點(diǎn)來(lái)實(shí)現(xiàn)的。?
光照(lighting),是這個(gè)階段的另一個(gè)主要部分。是使用物體表面的法向量來(lái)計(jì)算的。通過(guò)攝像機(jī)的位置和光源的位置,可以計(jì)算出給定頂點(diǎn)的光照屬性。?
?
對(duì)于坐標(biāo)系變換,我們從物體坐標(biāo)系開(kāi)始,每個(gè)物體都有自己的坐標(biāo)系,這有利于幾何變換,如平移,旋轉(zhuǎn)和縮放。?
之后,我們進(jìn)入到世界坐標(biāo)系,場(chǎng)景中的所有物體都具有統(tǒng)一的坐標(biāo)系。?
下一步是轉(zhuǎn)換到視圖空間,即攝像機(jī)坐標(biāo)系。想象一下:先在世界空間中放一個(gè)虛擬攝像機(jī),然后進(jìn)行坐標(biāo)變換,使得攝像機(jī)位于視圖空間的原點(diǎn),鏡頭對(duì)準(zhǔn)z軸的方向。現(xiàn)在我們定義一個(gè)所謂的視體(view frustrum),它用來(lái)決定了我們能夠通過(guò)虛擬的3D攝像機(jī)所能看到的場(chǎng)景,我們只需要把這些內(nèi)容渲染出來(lái)就行。?
?
之后,所有的頂點(diǎn)將被轉(zhuǎn)換剪切空間,并通過(guò)圖元裝配,組裝成圖元(primitive,三角形或線)。當(dāng)物體在視體的外,說(shuō)明我們不需要渲染這個(gè)物體,所以就簡(jiǎn)單丟棄它。當(dāng)一個(gè)物體有部分在視體內(nèi),我們需要進(jìn)行剪切,同時(shí)生成新的頂點(diǎn)。新頂點(diǎn)具有適當(dāng)?shù)牡募y理坐標(biāo)和顏色坐標(biāo)。?
接著我們執(zhí)行透視分割操作,其實(shí)就是實(shí)現(xiàn)了一個(gè)投影變換,把”近大遠(yuǎn)小“的效果實(shí)現(xiàn)出來(lái)。把一個(gè)視體轉(zhuǎn)換為歸一化的立方體。這個(gè)立方體的坐標(biāo)范圍:x和y在-1和1之間,z在0和1之間。同時(shí)視體內(nèi)的物體也一同進(jìn)行縮放。這樣一來(lái)得到的立方體,便于裁剪操作,也便于將來(lái)投影到平面(立方體只需要“扁平化”)。?
?
最后,我們轉(zhuǎn)換到屏幕空間。執(zhí)行的操作:根據(jù)窗口大小將x和y坐標(biāo)縮放到合適的坐標(biāo),這樣就得到2D圖片了。(請(qǐng)注意,頂點(diǎn)的z坐標(biāo)會(huì)保留,用于以后的深度操作)?
請(qǐng)注意,除了剪裁之外紋理坐標(biāo)也需要進(jìn)行轉(zhuǎn)換。還要注意除去不可見(jiàn)的表面[注2]。如出去立方體的背面,就是所謂的背面剔除。
光柵階段(Rasterization Stage)
光柵這個(gè)名詞不太好理解,新手可以想象成”透過(guò)一把梳子看世界“,類似于將連續(xù)的數(shù)據(jù)轉(zhuǎn)化成離散的數(shù)據(jù)。這里光柵階段是指矢量圖形轉(zhuǎn)化成像素點(diǎn)的過(guò)程。?
GPU需要遍歷2D圖像并進(jìn)行轉(zhuǎn)換將數(shù)據(jù)轉(zhuǎn)化為大量“像素候選”,即所謂的片段(Fragment,片段可以理解為像素的原型,但絕對(duì)不是指一大片像素)。片段是包含位置,顏色,深度,紋理坐標(biāo)等屬性的數(shù)據(jù)結(jié)構(gòu)。片段可能會(huì)最終成為圖像上的像素。片段是通過(guò)檢查原始圖元和和屏幕像素是否相交來(lái)生成的。如果一個(gè)片段與一個(gè)基元相交,但不與它的任何頂點(diǎn)相交,那么它的屬性必須通過(guò)頂點(diǎn)之間的屬性插值來(lái)計(jì)算得出。?
?
最后還有一些步驟來(lái)得到最終的像素。最終像素顏色的計(jì)算:結(jié)合紋理和顏色、光照等其他屬性,或片段與另一個(gè)半透明片段的結(jié)合(所謂的α混合),亦或是可選的霧化效果(另一個(gè)圖形效果)。[注3]
注1:齊次坐標(biāo)和四元數(shù)長(zhǎng)得很像,但卻是不同的概念,適用領(lǐng)域也不一樣。
注2:可見(jiàn)性檢查的一些具體操作:?
* 剪刀測(cè)試(檢查矩形面罩的可見(jiàn)度)?
* 模板測(cè)試(類似于剪刀測(cè)試,僅針對(duì)緩沖區(qū)中的任意像素模板)?
* 深度測(cè)試(比較片段的z坐標(biāo),丟棄更遠(yuǎn)的片段)?
* Alpha測(cè)試(檢查半透明碎片的可見(jiàn)度)
注3:在我們獲得最終結(jié)果之前,可以應(yīng)用像抗鋸齒這樣的附加程序:將一些像素寫入內(nèi)存供以后顯示。
reference
- GPUs - Graphics Processing Units
- 知乎:如何理解 OpenGL 中著色器、渲染管線、光柵化等概念?
- OpenGL技術(shù)之View Volume, Viewport, Screen的關(guān)系
- 維基百科-齊次坐標(biāo)
- 坐標(biāo)系統(tǒng)
- ?此外,還要講的就是? ?shader? 的編寫,這里推薦? ?http://bbs.gameres.com/upload/sf_20061018193133.pdf
總結(jié)
- 上一篇: 设计实现优雅修改redux数据流的一个库
- 下一篇: Anacoda 的 Python 包管理