[RTR4]2章 渲染管線

RTR4圖形渲染管線

本章展示了實(shí)時(shí)圖形的核心組成部分,圖形渲染管線,也可以簡(jiǎn)稱為管線.管線的主要功能是生成或者說(shuō)渲染一個(gè)二維圖像,通過(guò)給定的攝像機(jī),三維物體,光源等資源.渲染管線因此也是實(shí)時(shí)渲染的基本工具.渲染管線的過(guò)程如圖所示.圖像中的物體的位置和形狀是通過(guò)它們的幾何,環(huán)境特征和虛擬空間中攝像機(jī)的位置決定的.物體的外觀受材質(zhì)屬性,光源,紋理和陰影方程影響.

我們會(huì)解釋渲染管線的不同階段,更加關(guān)注功能而不是具體實(shí)現(xiàn).這些階段應(yīng)用上的相關(guān)細(xì)節(jié)會(huì)在后面幾章介紹.

渲染管線和結(jié)果.png

2.1 架構(gòu)

在現(xiàn)實(shí)世界,管線的概念以許多不同的形式出現(xiàn),從工廠裝配流水線到快餐廚房.它同樣被應(yīng)用于圖形渲染.一個(gè)管線包含許多階段,每個(gè)階段負(fù)責(zé)這個(gè)巨型任務(wù)的一部分.

各個(gè)管線階段是并行執(zhí)行的,每個(gè)階段都依賴前一階段的結(jié)果.理想情況下,一個(gè)非管線化的系統(tǒng)被劃分為了n條管線,那么效率會(huì)提升n倍.由此帶來(lái)的性能提升是使用管線的主要原因.舉例來(lái)說(shuō),一個(gè)人負(fù)責(zé)做面包,一個(gè)人負(fù)責(zé)加香腸,另一個(gè)人負(fù)責(zé)澆料,就能很快地準(zhǔn)備很多三明治.每個(gè)人在流水線作業(yè)中將結(jié)果迅速傳給下一個(gè)人,并且馬上開始做下一個(gè)三明治.如果每個(gè)人都需要20秒完成工作,那么整個(gè)三明治的制作最短速度就是20秒.管線各個(gè)階段并行處理,但是它們會(huì)等待最慢的階段完成工作.例如,假設(shè)加香腸需要花費(fèi)30秒,那么現(xiàn)在整個(gè)三明治制作的最短速度就是30秒.對(duì)于這個(gè)管線來(lái)說(shuō),加香腸這步就是瓶頸,因?yàn)樗鼪Q定了整個(gè)生產(chǎn)過(guò)程的速度.后面的澆料的步驟就會(huì)等待.

這種類型的管線結(jié)構(gòu)也在計(jì)算機(jī)實(shí)時(shí)渲染中有體現(xiàn).一種粗糙的劃分方式是將實(shí)時(shí)渲染管線劃分成四個(gè)主要階段:應(yīng)用(application),幾何處理(geometry processing),光柵化(rasterization)和像素處理(pixel processing),如圖所示.這個(gè)架構(gòu)是計(jì)算機(jī)實(shí)時(shí)圖形應(yīng)用的核心,并且也是后面幾節(jié)話題的基礎(chǔ).每個(gè)階段內(nèi)部也都是一個(gè)管線,也就意味著還有許多小階段.我們將圖中展示的階段的功能和他們各自的實(shí)現(xiàn)分開.功能階段擁有一個(gè)具體的執(zhí)行任務(wù),但是不會(huì)指定管線中執(zhí)行這個(gè)任務(wù)的方式.一種實(shí)現(xiàn)的方式可能是將兩個(gè)功能階段,都由一個(gè)單元執(zhí)行或通過(guò)可編程的核心執(zhí)行,如果將它們分成許多硬件單元執(zhí)行,就會(huì)消耗更多時(shí)間.

粗略管線全流程.png

渲染速度會(huì)通過(guò)每秒幀率(frames per second,FPS)表示.也可以用赫茲(Hz)表示.也可以用時(shí)間表示,以毫秒為單位的渲染一個(gè)畫面的時(shí)間.生成一幅圖像的時(shí)間是會(huì)變化的,取決于每幀計(jì)算的復(fù)雜度.FPS既能表示具體一幀的生成速度,也能描述使用期間的平均表現(xiàn).Hz被用于硬件,如顯示器,它們被設(shè)定為固定的頻率.

顧名思義,應(yīng)用階段是被應(yīng)用驅(qū)動(dòng)的,是被CPU上運(yùn)行的軟件程序?qū)崿F(xiàn)的.這些CPU通常擁有多個(gè)核心,能夠并行處理多線程的執(zhí)行.這也確保了CPU能高效地運(yùn)行應(yīng)用階段的大量的任務(wù).一些任務(wù)傳統(tǒng)上是由CPU處理的,包括碰撞檢測(cè),全局加速算法,動(dòng)畫,物理模擬和其他,取決于應(yīng)用的類型.下一個(gè)主要階段是幾何處理,需要處理變換,投影和其他的幾何處理.這個(gè)階段的任務(wù)是計(jì)算"該繪制什么","怎么繪制"和"繪制在哪".幾何階段就是典型的由圖形處理單元(Graphics Processing Unit,GPU)運(yùn)行的,GPU其中包括眾多可編程單元和固定操作單元.光柵化階段一般輸入三個(gè)頂點(diǎn),組成一個(gè)三角形,找到三角形內(nèi)部會(huì)包含的所有像素,然后將這些信息傳遞到下個(gè)階段.最終是像素處理階段,逐像素地執(zhí)行一個(gè)程序,來(lái)決定像素的顏色并可能執(zhí)行深度測(cè)試看這個(gè)像素是否可見(jiàn).這個(gè)階段也會(huì)執(zhí)行一些逐像素操作比如顏色混合.光柵化和像素處理階段是完全在GPU上執(zhí)行的.所有的階段和他們內(nèi)部的小管線會(huì)在接下來(lái)四節(jié)中講述.GPU如何處理這些階段的更多信息在第三章.

2.2 應(yīng)用階段

在應(yīng)用階段開發(fā)者擁有完全的控制權(quán),因?yàn)橥耆贑PU上執(zhí)行.因此,開發(fā)者能完全的決定如何實(shí)現(xiàn)并且也能為了更好的性能而修改.應(yīng)用階段的改變也能影響后續(xù)階段的性能.例如,應(yīng)用階段的算法或設(shè)置能降低需要渲染的三角形數(shù)量.

也就是說(shuō),一些應(yīng)用工作也能通過(guò)GPU執(zhí)行,使用區(qū)分的模式,叫計(jì)算著色器(compute shader).這個(gè)模式將GPU視作高度并行的通用處理器,忽略它為渲染圖形特別設(shè)置的功能.

在應(yīng)用階段的最后,需要渲染的幾何體會(huì)被送到幾何處理階段.這些幾何體被稱為渲染面元(rendering primitives),也就是最終會(huì)在屏幕里顯示的點(diǎn),線和三角形(無(wú)論使用什么顯示設(shè)備).這是應(yīng)用階段最重要的任務(wù).

應(yīng)用階段基于軟件的實(shí)現(xiàn)的結(jié)果就是它不會(huì)被分為子階段.而后續(xù)三個(gè)階段會(huì).然而,為了提升性能表現(xiàn),這個(gè)過(guò)程也會(huì)并行地在一些處理核心上執(zhí)行.在CPU設(shè)計(jì)中,被稱為超級(jí)標(biāo)量體系建設(shè)(superscalar construction),因?yàn)樗軌蛲瑫r(shí)執(zhí)行多個(gè)進(jìn)程.18.5節(jié)展示了用于多處理核心的許多方法.

在應(yīng)用階段被廣泛實(shí)現(xiàn)的處理過(guò)程是碰撞檢測(cè).在兩個(gè)物體間的碰撞被檢測(cè)出來(lái)后,會(huì)有一些反應(yīng)反饋到兩個(gè)物體中,也會(huì)給設(shè)備反饋.應(yīng)用階段也是要處理其他源的輸入的,比如鍵鼠或頭戴式設(shè)備.由于輸入的不同,會(huì)進(jìn)行許多不同的動(dòng)作.加速算法,像具體的剔除算法,還有其他管線不能處理的東西也在這里執(zhí)行.

2.3幾何處理

幾何處理階段負(fù)責(zé)大多數(shù)逐三角形和逐頂點(diǎn)的操作.這個(gè)階段也被劃分為如下的功能階段:頂點(diǎn)著色,投影,裁剪和屏幕映射.

幾何處理過(guò)程.png

2.3.1 頂點(diǎn)著色

頂點(diǎn)著色有兩個(gè)主要任務(wù),一是計(jì)算頂點(diǎn)的位置,二是決定期望的頂點(diǎn)數(shù)據(jù)的輸出形式,比如法線和紋理坐標(biāo).傳統(tǒng)上很多物體的著色都是通過(guò)在每個(gè)頂點(diǎn)位置和法線應(yīng)用光照并且儲(chǔ)存在頂點(diǎn)處的顏色.這些顏色接下來(lái)會(huì)在三角形中插值.因此,可編程的頂點(diǎn)處理單元被叫做頂點(diǎn)著色器.隨著現(xiàn)代GPU的到來(lái),隨著更多的逐像素著色的出現(xiàn),頂點(diǎn)著色階段更加的一般,并且可能不會(huì)再計(jì)算著色結(jié)果了,這取決于開發(fā)者的目的.頂點(diǎn)著色器現(xiàn)在成為了一般的單元,能夠設(shè)置每個(gè)頂點(diǎn)相關(guān)的數(shù)據(jù).舉個(gè)例子,頂點(diǎn)著色器可以通過(guò)4.4章和4.5章的方式讓物體動(dòng)起來(lái).

我們從描述頂點(diǎn)位置是如何計(jì)算的開始,我們需要一系列的坐標(biāo).在從頂點(diǎn)位置轉(zhuǎn)換到屏幕上的過(guò)程中,模型需要轉(zhuǎn)換到許多不同的空間和坐標(biāo)系統(tǒng)中.起初,模型擁有自身的模型空間,這也意味著它沒(méi)有進(jìn)行變換.每個(gè)模型都能與一個(gè)模型變換相關(guān)聯(lián),這樣它能被定位和定向.一個(gè)模型能夠有多個(gè)模型變換,這使得一個(gè)模型的諸多復(fù)制(也叫實(shí)例)能在一個(gè)場(chǎng)景中擁有不同位置,指向和大小,而不需要重新復(fù)制基本的幾何圖形.

模型的頂點(diǎn)和法線會(huì)通過(guò)模型轉(zhuǎn)換變換.對(duì)象的坐標(biāo)被稱為模型坐標(biāo),經(jīng)過(guò)模型變換后,模型被定位在世界空間的世界坐標(biāo)上.世界空間是唯一的,在模型通過(guò)各自的模型變換后,所有的模型都存在于相同的世界空間中.

如前面所說(shuō),只有被攝像機(jī)看到的模型才會(huì)被渲染.相機(jī)在世界空間有個(gè)坐標(biāo)和方向,這被用于放置相機(jī)和瞄準(zhǔn)相機(jī)方向.為了便于投影和裁剪,相機(jī)和所有的模型都會(huì)通過(guò)視圖變換.視圖變換的目的是將相機(jī)放置在原點(diǎn)并使它看向z軸負(fù)半軸,y軸指向上,x軸指向右.我們使用-z軸,一些文章可能傾向于看向+z軸.區(qū)別主要是語(yǔ)義上的,因?yàn)樽儞Q是相同的.視圖變換后真正的位置和方向取決于底層API.這個(gè)空間被稱作攝像機(jī)空間,或者說(shuō)觀察空間或視點(diǎn)空間.視圖變換如何影響相機(jī)和模型的例子如圖所示.模型變換和視圖變換會(huì)使用4x4的矩陣,這是第4章的話題.我們需要認(rèn)識(shí)到頂點(diǎn)的位置和法線可以用程序員習(xí)慣的任何方式計(jì)算.

視圖變換.png

接下來(lái),我們介紹頂點(diǎn)著色的第二種輸出.為了呈現(xiàn)一個(gè)真實(shí)的場(chǎng)景,渲染物體的形狀和位置是不夠的,還需要對(duì)外觀進(jìn)行建模.這種描述包含每個(gè)物體的材質(zhì).也包含光源在物體上的效果.材質(zhì)和燈光能夠以多種方式建模,從簡(jiǎn)單的顏色到對(duì)物理描述精細(xì)的表示.

決定燈光在材質(zhì)上的影響的操作被稱為著色.它包括計(jì)算計(jì)算物體上不同點(diǎn)的著色方程.通常,一些計(jì)算是在模型頂點(diǎn)的幾何處理階段,而另一些是在逐像素處理階段.每個(gè)頂點(diǎn)能存儲(chǔ)許多材質(zhì)數(shù)據(jù),例如頂點(diǎn)位置,法線,顏色,或者其他數(shù)字信息等計(jì)算著色方程需要的.頂點(diǎn)著色結(jié)果(可以是顏色,向量,紋理坐標(biāo)等以及其他著色數(shù)據(jù))會(huì)接下來(lái)發(fā)送到光柵化和像素處理階段,來(lái)通過(guò)插值計(jì)算表面的著色.

GPU頂點(diǎn)著色器的頂點(diǎn)著色的討論會(huì)特別在本書的3-5章.

作為頂點(diǎn)著色的一部分,渲染系統(tǒng)執(zhí)行投影然后裁剪,將可見(jiàn)范圍轉(zhuǎn)換為一個(gè)單位立方體,端點(diǎn)為(-1,-1,-1)和(1,1,1).可以不同的范圍來(lái)使用和定義相同體積,比如[0,1].單位立方體也被稱為標(biāo)準(zhǔn)視圖空間(canonical view volume).投影是首先完成的,在GPU上是通過(guò)頂點(diǎn)著色器完成的.有兩種通常被使用的投影方法,稱為正交投影(也叫平行投影)和透視投影.如圖所示.事實(shí)上,正交投影是透視投影的一種平行形式.其他的投影也會(huì)有用,特別是在建筑領(lǐng)域,比如斜軸(oblique)和軸測(cè)(axonometric)投影.老式游戲街機(jī)Zaxxon是以后者的名字命名的.

正交和透視投影.png

注意,透視是用矩陣表示的,因此有時(shí)它也可能與幾何變換的剩余部分連接在一起.

正交投影視圖的視圖體(view volume,指投影前的視體空間)通常是一個(gè)矩形盒子,正交投影變換將這個(gè)視圖體轉(zhuǎn)換成單位正方體.正交投影的主要特征是平行的線轉(zhuǎn)換后依舊平行.變換過(guò)程包含了平移和縮放.

透視投影就有一些復(fù)雜,在這個(gè)投影中,物體離相機(jī)越遠(yuǎn),經(jīng)過(guò)投影后它就越小.另外,平行線可以在地平線上相交.因此,透視變換模仿了我們感知物體大小的方式.幾何上來(lái)講,視圖體也叫視錐體,是底為矩形的截頂棱錐.視錐體也被投影成了單位立方體.正交變換和透視變換都可以通過(guò)4x4的矩陣來(lái)構(gòu)造(第四章),并且在任何一個(gè)變換后,模型所在的坐標(biāo)系稱為裁剪坐標(biāo)系.這些坐標(biāo)實(shí)際上是齊次坐標(biāo),發(fā)生在除w之前.GPU的頂點(diǎn)著色器必須總是輸出這種類型的坐標(biāo),因?yàn)橐屜乱粋€(gè)功能階段準(zhǔn)確運(yùn)行,比如裁剪.

盡管這些矩陣將一個(gè)體積轉(zhuǎn)換為了另一個(gè)體積,他們稱為投影是因?yàn)樵陲@示后,z坐標(biāo)并不存儲(chǔ)在生成的圖像中,而是在深度緩沖中,2.5章會(huì)介紹.也就是說(shuō),模型從3維空間投影到了2維空間.

2.3.2 可選的頂點(diǎn)處理

每個(gè)管線都擁有上文所說(shuō)的頂點(diǎn)處理,一旦處理結(jié)束,GPU也會(huì)有一些可選的操作步驟.按順序分別是:細(xì)分曲面,幾何著色,流輸出.它們的使用與否取決于硬件(不僅是GPU)的支持,也取決于開發(fā)者的意愿.它們都各自獨(dú)立,一般來(lái)說(shuō)用得不多.第三章會(huì)介紹更多.

第一個(gè)可選階段是曲面細(xì)分.想象一下你擁有一個(gè)反射球物體.如果你僅僅將它以三角形集合的方式展現(xiàn)的話, 你會(huì)遇到表現(xiàn)的問(wèn)題.你的球可能在5米遠(yuǎn)以外看得不錯(cuò),但是靠近后就看到獨(dú)立的三角形了,特別是沿著輪廓的部分.如果你把球用更多的三角形表示來(lái)改善圖像質(zhì)量,那在球離攝像機(jī)很遠(yuǎn)的時(shí)候,就會(huì)浪費(fèi)更多的處理時(shí)間和內(nèi)存來(lái)處理僅僅是幾個(gè)像素大小的球.有了曲面細(xì)分,一個(gè)曲面可以生成相當(dāng)數(shù)量的三角形.

我們已經(jīng)討論一些三角形了,但是到此為止我們的管線還只能處理頂點(diǎn).頂點(diǎn)能夠用來(lái)表現(xiàn)點(diǎn),直線,三角形或其他物體.頂點(diǎn)也能用來(lái)表示一個(gè)曲面,例如球體.這些表面能通過(guò)一系列的patch表現(xiàn)出來(lái),每個(gè)patch都是通過(guò)一組頂點(diǎn)來(lái)描述的.曲面細(xì)分階段內(nèi)也包含了一組階段:外殼著色器(hull shader),曲面細(xì)分,域著色器(domain shader).這些步驟將一系列的patch頂點(diǎn)(一般情況下)轉(zhuǎn)換為更多的頂點(diǎn),并接下來(lái)用來(lái)形成一系列新的三角形.畫面的攝像機(jī)能用來(lái)決定需要生成多少個(gè)三角形,patch離得近就生成得多,patch離得遠(yuǎn)就生成得少.

下一個(gè)可選階段是幾何著色.這個(gè)著色器早于曲面細(xì)分著色器并且在GPU上應(yīng)用地更廣泛.就像曲面細(xì)分著色器,幾何著色也是接收各種類型的圖元,然后產(chǎn)生新的頂點(diǎn).這是一個(gè)非常簡(jiǎn)單的階段,因?yàn)閯?chuàng)建頂點(diǎn)的范圍非常有限,輸出的圖元類型也非常有限.幾何著色器有幾個(gè)用途,其中最著名的是粒子生成.設(shè)想模擬煙花爆炸的過(guò)程.每個(gè)火球都能用一個(gè)頂點(diǎn)來(lái)表示.幾何著色器能夠?qū)⒚總€(gè)頂點(diǎn)轉(zhuǎn)換成一個(gè)面對(duì)著觀眾的平面(由兩個(gè)三角形組成),并覆蓋一定數(shù)量的像素.這種圖元著色毫無(wú)疑問(wèn)更有說(shuō)服力.

最后的可選階段是流輸出.這個(gè)階段能讓我們把GPU當(dāng)做幾何引擎來(lái)使用.不把處理過(guò)的頂點(diǎn)之間傳入接下來(lái)的管線步驟從而將其渲染在屏幕上,而是我們可以選擇將這些頂點(diǎn)輸出到數(shù)組中做進(jìn)一步處理.在后續(xù)環(huán)節(jié)這些數(shù)據(jù)能被CPU或GPU自身使用.這個(gè)階段也經(jīng)常用來(lái)做粒子模擬,正如上文的煙花例子.

這三個(gè)階段按曲面細(xì)分,幾何著色,流輸出的順序執(zhí)行,每個(gè)階段都是可選的.不管使用了哪個(gè)選項(xiàng),如果我們繼續(xù)沿著管線進(jìn)行,會(huì)得到一組其次坐標(biāo)的頂點(diǎn),然后會(huì)檢查這些頂點(diǎn)是否會(huì)被攝像機(jī)看到.

2.3.3 裁剪

只有完全或部分在視體(view volume)內(nèi)的圖元才會(huì)進(jìn)入光柵化階段(和后面的像素處理階段),然后它們會(huì)被繪制在屏幕上.完全在視體內(nèi)的圖元會(huì)被原封不動(dòng)地傳遞到下一階段.完全在視體外部的圖元不會(huì)被傳遞到下一階段,所以它們不會(huì)被渲染.部分在視體內(nèi)部的圖元是需要裁剪的.例如,一條直線有一個(gè)頂點(diǎn)在視體外,一個(gè)頂點(diǎn)在視體內(nèi),就會(huì)被根據(jù)視體裁剪,于是在外部的頂點(diǎn)就會(huì)被位于直線和視體角點(diǎn)處的新頂點(diǎn)所取代.投影矩陣的使用意味著經(jīng)過(guò)投影轉(zhuǎn)換的圖元會(huì)被單位立方體所裁剪.在裁剪之前應(yīng)用視圖變換和投影變換的好處是它能讓裁剪問(wèn)題保持一致,圖元總是根據(jù)單位立方體裁剪.

裁剪.png

裁剪過(guò)程如圖所示.除了這六個(gè)視體的裁剪平面以外,用戶能定義額外的裁剪平面來(lái)明顯地裁剪對(duì)象.圖19.1展示了這種裁剪,稱作切片(sectioning).

Scetioning裁剪.png

裁剪的步驟使用經(jīng)過(guò)投影變換的4個(gè)值的其次坐標(biāo).在透視空間,沿著三角形的插值并不是線性的.其次坐標(biāo)的第四個(gè)值的存在使應(yīng)用了透視投影后的插值更正確.最后會(huì)執(zhí)行透視除法,這會(huì)把三角形的位置放置在三維的歸一化設(shè)備坐標(biāo)系(normalized device coordinates,NDC)中.正如前文所說(shuō),視體的坐標(biāo)范圍是從(-1,-1,-1)(1,1,1)的.幾何處理的最后一步是將這個(gè)空間轉(zhuǎn)換為窗口坐標(biāo).

2.3.4 屏幕映射

只有處于視體內(nèi)部并經(jīng)過(guò)裁剪的圖元才會(huì)進(jìn)入屏幕映射階段,進(jìn)入這個(gè)階段時(shí)的坐標(biāo)亦然是3維的.每個(gè)圖元的x與y坐標(biāo)會(huì)轉(zhuǎn)換成屏幕空間坐標(biāo).屏幕空間坐標(biāo)以及z坐標(biāo)也會(huì)被稱為視窗坐標(biāo).設(shè)想畫面會(huì)被渲染至一個(gè)最小角落(x_1,y_1)最大角落(x_2,y_2), x_1<x_2, y_1<y_2.屏幕映射先進(jìn)行平移然后縮放.新的x和y坐標(biāo)被稱作屏幕坐標(biāo),而z坐標(biāo)(OpenGL是[-1,+1],DirectX是[0,1])也會(huì)被映射到默認(rèn)[0,1]之間.這可能根據(jù)API而不同,然而,屏幕坐標(biāo)和深度坐標(biāo)會(huì)一起進(jìn)入光柵化階段.屏幕映射的過(guò)程如圖所示.

屏幕映射.png

接下來(lái),我們描述整數(shù)值和浮點(diǎn)數(shù)值是怎樣和像素(以及紋理坐標(biāo))值相聯(lián)系的.給定水平像素?cái)?shù)組并使用笛卡爾坐標(biāo),最左邊的像素的左邊緣以浮點(diǎn)數(shù)表示是0.0f.OpenGL一直使用此方案,而DX10以后才應(yīng)用這版本.這個(gè)像素的重心是0.5,所以,像素0-9覆蓋了0.0-10.0的范圍.可以簡(jiǎn)單表示為:
d=floor(c), c=d+0.5f
d是像素的整數(shù)索引,c是像素內(nèi)連續(xù)的浮點(diǎn)數(shù)值.

盡管所有的API的像素位置都是從左向右遞增的,但是從上到下是遞增遞減是不一致的.OpenGL全程使用笛卡爾系統(tǒng),將左下角作為最小的元素值,而DX有時(shí)根據(jù)上下文將左上作為第一個(gè)像素元素值.這種差異在從一個(gè)API遷移到另一API時(shí)需要注意.

2.4 光柵化

有了變換和投影后的頂點(diǎn)以及相應(yīng)的著色信息(都是來(lái)自幾何處理),下一個(gè)階段的目的是找到圖元(也就是三角形)內(nèi)部的所有的像素(pixels是picture elements的縮寫).我們把這個(gè)過(guò)程叫做光柵化,并且它被分成了兩個(gè)子階段:三角形裝配(也叫圖元裝配)和三角形遍歷.如圖所示.注意這些過(guò)程同樣能處理點(diǎn)和線,但是因?yàn)槿切蔚奶幚砀悠毡?所以才叫做三角形裝配和三角形遍歷.光柵化也被叫做掃描轉(zhuǎn)換(scan conversion),是將屏幕空間中的二維點(diǎn)坐標(biāo)(帶有深度信息,和許多其他著色信息)轉(zhuǎn)換到屏幕中的像素上.光柵化也能被認(rèn)為是連接幾何處理和像素處理的同步點(diǎn),因?yàn)橥ㄟ^(guò)光柵化,三角形從三個(gè)頂點(diǎn)最終轉(zhuǎn)換到了像素處理階段.

光柵化與像素處理過(guò)程.png

三角形該如何覆蓋一個(gè)像素取決于你的管線是如何設(shè)置的.比如,你可能通過(guò)對(duì)點(diǎn)采樣來(lái)決定像素在不在三角形內(nèi).最簡(jiǎn)單的情況是每個(gè)像素使用一個(gè)位于像素中心的采樣點(diǎn),并且如果中心點(diǎn)在三角形內(nèi)部,則對(duì)應(yīng)的像素就被認(rèn)為在三角形的中心.也可以使用每像素多于一個(gè)的采樣點(diǎn),使用超采樣或MSAA技術(shù)(見(jiàn)5.4.2章).還有一種方法是使用保守光柵化,它的定義是只要像素內(nèi)有部分處于三角形中,那么就認(rèn)為這個(gè)像素位于三角形中.

2.4.1 三角形裝配

在這個(gè)階段,會(huì)計(jì)算差分,邊緣函數(shù)和其他三角形的數(shù)據(jù).這些數(shù)據(jù)可能被用于三角形遍歷,也可能用于計(jì)算幾何階段的各種著色數(shù)據(jù)的插值.會(huì)有固定功能的硬件來(lái)做這個(gè)工作.

2.4.2 三角形遍歷

在這個(gè)階段,每個(gè)像素會(huì)確認(rèn)它和三角形的覆蓋情況,并且被覆蓋的像素會(huì)生成片元.其他精巧的采樣方法見(jiàn)5.4章.找到那個(gè)像素或采樣點(diǎn)位于三角形中的過(guò)程叫做三角形遍歷.每個(gè)三角形中的片元屬性通過(guò)在三角形三個(gè)頂點(diǎn)之間插值生成.這些屬性包括片元深度以及其他從幾何處理階段傳遞過(guò)來(lái)的著色數(shù)據(jù).McCormack等人對(duì)三角形遍歷提供了更多的信息.這里也會(huì)進(jìn)行透視校正插值.圖元內(nèi)所有的像素或采樣點(diǎn)接下來(lái)會(huì)被送進(jìn)像素處理階段.

2.5 像素處理

在這里,因?yàn)榍拔闹v過(guò)的階段,所有的像素都被認(rèn)為在三角形或其他圖元內(nèi)部.像素處理階段被劃分為像素著色和合并,如圖所示.像素處理是對(duì)圖院內(nèi)的像素和采樣點(diǎn)進(jìn)行逐像素和逐采樣點(diǎn)的計(jì)算和操作的階段.

光柵化與像素處理過(guò)程.png

2.5.1 像素著色

各種逐像素著色的計(jì)算會(huì)在像素著色環(huán)節(jié)執(zhí)行,以經(jīng)過(guò)插值的著色數(shù)據(jù)作為輸入.最終的結(jié)果是需要傳遞到下個(gè)階段的一個(gè)或幾個(gè)顏色.不像三角形裝配和三角形遍歷階段由特定的硬件部分執(zhí)行,像素處理階段是通過(guò)可編程的GPU核心執(zhí)行的.程序員會(huì)為像素著色器(片元著色器)提供程序,其中包含想要執(zhí)行的操作和計(jì)算.大量各種各樣的技術(shù)會(huì)在這里應(yīng)用,其中最重要的是紋理.第6章會(huì)詳細(xì)介紹紋理.簡(jiǎn)單來(lái)說(shuō),在一個(gè)物體上應(yīng)用紋理相當(dāng)于將一張或多張圖片"粘"到物體上,出于各種不同的目的.一個(gè)簡(jiǎn)單的例子,如圖所示.紋理圖片可以是一維的,二維的或三維的,二維最為常見(jiàn).最簡(jiǎn)要地概括,最終的產(chǎn)品是為每個(gè)片元生成一個(gè)顏色值,這個(gè)顏色值會(huì)應(yīng)用在接下來(lái)的階段中.

紋理示意圖.png

2.5.2 合并

每個(gè)像素的信息儲(chǔ)存在顏色緩沖(color buffer)中,顏色緩沖是關(guān)于顏色的二維數(shù)組(每個(gè)顏色有紅綠藍(lán)三個(gè)分量組成).合并階段的任務(wù)是將像素著色階段產(chǎn)生的片元顏色值與在顏色緩沖中存儲(chǔ)的顏色進(jìn)行組合.這個(gè)階段也稱做ROP,指管線光柵操作(raster operation (pipeline))或渲染輸出單元(render output unit),取決于你詢問(wèn)的對(duì)象.與著色階段不同,執(zhí)行合并的GPU子單元不是充分可編程的.然而是高度可配置的,可以實(shí)現(xiàn)不同的效果.

這個(gè)階段也負(fù)責(zé)處理可見(jiàn)性的問(wèn)題.這意味著當(dāng)整個(gè)場(chǎng)景被渲染完畢后,顏色緩沖中應(yīng)該包含場(chǎng)景中能被攝像機(jī)看到的圖元的顏色(也就是片元遮擋的問(wèn)題).對(duì)于大多數(shù)甚至全部圖形硬件來(lái)說(shuō),這步通過(guò)z-buffer算法(也就是深度緩沖算法)解決.深度緩沖和顏色緩沖具有相同的大小,并且對(duì)于每個(gè)像素都儲(chǔ)存了當(dāng)前距離攝像機(jī)最近的片元的深度.這意味著當(dāng)圖元被渲染到像素上,圖元上這個(gè)像素的深度就會(huì)計(jì)算并和深度緩沖中相同位置的像素深度進(jìn)行比較.如果新的深度比緩沖中的深度小,那么當(dāng)前渲染的圖元更接近攝像機(jī).于是,這個(gè)位置的深度緩沖和顏色緩沖將會(huì)被更新為當(dāng)前圖元的深度.如果正在計(jì)算的像素的深度比緩沖中的深度大,那么這個(gè)像素的顏色和深度將被拋棄.z-buffer算法很簡(jiǎn)單,是O(N)復(fù)雜度(N是被渲染的圖元的數(shù)量),并適用于可以為每個(gè)(相關(guān))像素計(jì)算z值的任何圖形圖元。同樣需要注意,z-buffer算法允許大多數(shù)圖元以任何順序渲染,這也是它好用的原因之一.然而,深度緩沖僅僅為屏幕上的每個(gè)點(diǎn)儲(chǔ)存一個(gè)深度值,所以它不能用于部分透明的圖元.透明圖元必須在不透明圖元之后渲染,并且以前后順序呈現(xiàn),或者單獨(dú)使用獨(dú)立于順序的算法(5.5章介紹).透明度是z-buffer算法的主要弱點(diǎn).

我們提到了顏色緩沖用來(lái)儲(chǔ)存顏色,深度緩沖儲(chǔ)存每個(gè)像素的深度.然而,也有其他的通道和緩沖能夠用來(lái)過(guò)濾和捕獲片元信息.透明度通道(alpha channel)和顏色緩沖相關(guān)并且儲(chǔ)存了每個(gè)像素的透明度值(5.5章介紹).在舊的API中,透明度通道也被用來(lái)通過(guò)透明度測(cè)試丟棄像素.如今我們可以在像素著色器中插入丟棄的操作,或者其他的計(jì)算也能用來(lái)激活丟棄操作.這種類型的測(cè)試能用來(lái)確保完全透明的片元不會(huì)影響深度緩沖.

模板緩沖(stencil buffer)是一個(gè)幕后緩沖,用來(lái)記錄已渲染的圖元的位置.它一般每個(gè)像素包含8位.圖元可以通過(guò)各種操作被渲染進(jìn)模板緩沖,然后模板緩沖的內(nèi)容能夠被用來(lái)控制顏色緩沖和深度緩沖的寫入.舉例來(lái)說(shuō),設(shè)想一個(gè)實(shí)心圓形被畫入了模板緩沖.隨后能夠進(jìn)行操作,只允許在這個(gè)圓形出現(xiàn)的位置,將后續(xù)圖元繪制進(jìn)顏色緩沖.模板緩沖對(duì)于生成某些特別的效果十分有用.這些管線最后的操作被稱為光柵操作(raster operations, ROP)或混合操作(blend operations).可以做把當(dāng)前正在處理的像素顏色和顏色緩沖中已經(jīng)存在的顏色進(jìn)行混合的操作.這中操作可以實(shí)現(xiàn)透明度或顏色采樣疊加的效果.如上所說(shuō),混合操作在API中是可配置的而不是可編程的.然而,一些API也提供對(duì)于光柵順序視圖(raster order views),也稱為像素著色器排序(pixel shader ordering)的支持,它支持可編程的混合能力.

幀緩沖一般就包括上面所說(shuō)的緩沖區(qū).

當(dāng)圖元到達(dá)并且通過(guò)了光柵化階段,對(duì)于攝像機(jī)的視角可見(jiàn)的圖元就會(huì)被展示在屏幕上.屏幕展示的是顏色緩沖中的內(nèi)容.為了避免觀眾看到圖元正在進(jìn)行光柵化和發(fā)送到屏幕的過(guò)程,通常會(huì)使用雙緩沖.這意味著屏幕圖像的渲染是發(fā)生在后臺(tái)的,在后緩沖中(back buffer).一旦圖像在后緩沖中被渲染完成,后緩沖中的內(nèi)容就會(huì)和正在展示的前緩沖進(jìn)行切換.交換的過(guò)程發(fā)生在垂直回溯(vertical retrace)期間,此時(shí)進(jìn)行是安全的.

有關(guān)不同緩沖區(qū)的內(nèi)容見(jiàn)5.4.2,23.6和23.7節(jié).

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容