概述
在渲染管線中弹谁,最慢的階段決定整個渲染的速度。
我們一般使用吞吐量(throughput)來描述一個階段的處理速度芝加,而不是幀率备畦。
因為幀率會受到設(shè)備更新的限制而導(dǎo)致實際速度比幀率所標示的更慢。
一個例子:
假設(shè)一個設(shè)備為60赫茲仁期,這意味著這個設(shè)備16.666666ms刷新一次桑驱,這時恰好有一管線階段花費了62.5ms執(zhí)行完成,由于63大于16.666666*3跛蛋,小于16.666666*4熬的,所以他實際上想要最終完成工作必須等待下一次設(shè)備刷新。所以真實的執(zhí)行時間折算下來其實不止62.5ms而是趨近于66ms赊级。當然押框,如果關(guān)閉了垂直同步就另當別論了。
一個渲染管線可以按照執(zhí)行順序分成四大階段:
應(yīng)用階段
幾何階段
光柵階段
像素處理階段
這些階段又可以細分為更多的子階段理逊,注意這些都是功能性的分配橡伞,在實現(xiàn)上為了效率等因素往往會合并一些階段或者拆分一些階段等等。
下面是一張圖:
一晋被、應(yīng)用階段 ?Application stage
開發(fā)者對application stage發(fā)生的事有絕對的控制權(quán)兑徘,因為這個階段是在CPU上執(zhí)行的。例如羡洛,一個application stage的算法或設(shè)置可以減少被渲染的三角形的數(shù)量挂脑。
但是一些application work也可以通過GPU完成,這要用到計算著色器(compute shader)欲侮。compute shader把GPU當成一個高度并行的通用處理器(highly parallel general processor)崭闲,而忽略了它渲染圖形的專門功能。
在application stage的末尾威蕉,要被渲染的geometry被提供給geometry processing stage镀脂。這些是rendering primitives,例如忘伞,points, lines,和triangles薄翅,這些最終可能會出現(xiàn)在屏幕上(或者別的任何輸出設(shè)備)沙兰。這是application stage最重要的任務(wù)
二、幾何處理階段?Geometry processing stage
Geometry processing?stage負責?(GPU上)大部分per-triangle(逐三角形的)翘魄、per-vertex(逐頂點的)操作鼎天。每個階段又可以進一步分成以下幾個功能性階段(functional stages): vertex shading, projection, clipping, and screen mapping。如下圖:
Vertex Shading
Vertex Shading有兩個主要的任務(wù)暑竟,即:
1.計算頂點(vertex)的位置(postition)
2.計算任何程序員可能想要的頂點輸出數(shù)據(jù)(vertex output data)斋射,例如法線、紋理坐標但荤。
傳統(tǒng)上罗岖,大部分物體著色(shade of an object)是通過對每個頂點位置和法線應(yīng)用光照并把產(chǎn)生的顏色存儲在頂點(vertex)中來計算的。這些顏色將會在每一個三角形內(nèi)部插值腹躁。因為這個原因桑包,這個可編程的頂點處理單元被命名為vertex shader。隨著現(xiàn)代GPU的出現(xiàn)纺非,隨著部分或全部的逐像素著色(per-pixel shading)的出現(xiàn)哑了,vertex shading stage功能變得更加泛化,可能根本不進行任何著色(或者說不計算任何著色方程烧颖,shading equation)弱左,這取決于程序員的意圖。現(xiàn)在vertex shader是一個更通用的單元炕淮,用于設(shè)置和每個頂點相關(guān)聯(lián)的數(shù)據(jù)拆火。
在顯示到屏幕的過程中,一個模型(model)被變換到好幾個不同的空間(spaces)或者坐標系統(tǒng)(coordinate systems)涂圆。最初一個模型存在于它自己的模型空間(model space)榜掌,每一個模型都有變化屬性(model transform),這樣它就可以被定位或定向乘综。也有的是單個模型(single model)與多個model transforms相關(guān)聯(lián)憎账。也允許在同一場景中,相同模型(same model)的多個實例有不同的位置卡辰、朝向或尺寸胞皱,而且不需要復(fù)制的基本幾何體(basic geometry)。
受model transform變換影響的是模型(model)的頂點(vertices)和法線(normals)九妈。模型內(nèi)的坐標叫作模型坐標(model coordinates)反砌,模型加載到場景后,模型就處于世界坐標(world coordinates)或世界空間(world space)萌朱。world space是唯一的宴树,所有模型經(jīng)過空間轉(zhuǎn)換后,就都處于同一個空間/坐標系了晶疼。
在渲染時酒贬,只有被camera(或observer)看到的模型(models)才會被渲染又憨。Camera在世界空間有一個位置(location)和方向(direction),用于放置和對準相機锭吨。為了方便投影(projection)和裁剪(clipping)蠢莺,相機和所有模型(models)會經(jīng)歷view transform。View transform的目的是把camera放置在原點(origin)上零如,并使得camera看向負z軸(negative z-axis)躏将,y?軸朝上(pointing upward),x?軸朝右考蕾。本書使用z軸朝內(nèi)的約定(右手坐標系)祸憋。模型經(jīng)view transform變換后就處于camera space了,或者叫view space肖卧,eye space蚯窥。下圖是一個view transform影響camera和models的例子。
為了產(chǎn)生一個具有真實感的場景喜命,僅僅渲染物體的形狀和位置是不夠的,也要渲染他們的“外觀”(appearance)河劝。這個描述包含每個物體的材質(zhì)和照射到物體的光源的效果壁榕。材質(zhì)和光源多種方式建模,從簡單的顏色到復(fù)雜的物理描述赎瞎。
決定燈光在材質(zhì)上的效果的操作被稱為著色(shading)牌里。它涉及到在物體各個點上計算著色方程shading equation。通常务甥,這些計算的一部分是在模型頂點(vertices)的幾何處理階段完成的牡辽,而另一些是在per-pixel處理時完成的。各種各樣的材質(zhì)數(shù)據(jù)可以被存儲在每個頂點(vertex)上敞临,如:點的位置态辛,法線 ,顏色或者任何別的用于計算著色方程的數(shù)值信息挺尿。Vertex shading的結(jié)果(可能是colors, vectors, texture coordinates奏黑,以及別的數(shù)據(jù))被送到rasterization和pixel processing階段,被插值编矾,被用于計算表面著色(shading of the surface)熟史。
作為vertex shading的一部分,渲染系統(tǒng)完成projection(投影)和隨后的clipping(裁剪)窄俏,這會把視景體(view volume)轉(zhuǎn)換成一個單位立方體(unit cube)蹂匹,它的頂點坐標范圍為(-1, -1, -1)和(1, 1, 1)。這個單位立方體被稱為標準視景體(canonical view volume)凹蜈。首先完成投影(Projection)限寞,在GPU上是通過vertex shader完成的忍啸。有兩種常見的投影方法,即正交投影(orthographic projection)昆烁,也稱作平行投影(parallel projection)吊骤,和透視投影(perspective projection)。另外幾種投影方式静尼,如:oblique和axonometric投影白粉。
正交投影的視景體(view volume)通常是一個的長方體,而正交投影會把這個長文體變換成一個單位立方體(unit cube)鼠渺。正交投影的主要特點是變換后平行線仍然保持平行鸭巴。這個變換是平移和綻放的組合。
透視投影更復(fù)雜點拦盹。在透視投影中鹃祖,物體離像機越遠,物體在投影后看起來越小普舆。另外恬口,平行線可能會相交。投視變換模仿我們感知物體尺寸的方式沼侣。在幾何學(xué)上祖能,透視投影的視景體(view volume)被稱為視錐體(frustum),即一個截頭錐體蛾洛。視錐體也會被變換成一個單位立方體(unit cube)养铸。正交變換和透視變換都可以用4×44×4矩陣來構(gòu)造,經(jīng)過兩者中任何一種變換后轧膘,都說模型處于裁剪空間或裁剪坐標(clip coordinates)钞螟。這些實際上是齊次坐標(homogeneous coordinates),出現(xiàn)在被w除之前谎碍。為了使下一個功能階段鳞滨,clipping(裁剪),正確工作蟆淀,GPU的vertex shader必須總是輸出這種類型的坐標太援。
盡管這些矩陣把一個volume(視景體)變換成另一個(unit cube),他們被稱投影(projections)扳碍,因為顯示后(after display)提岔,zz坐標不再存儲在生成的圖像中,而是存儲在z-buffer中笋敞。以這種方式碱蒙,模型被從三維空間投影到了二維空間。
Optional Vertex Processing
上面講的vertex processing是每個渲染管線都有的。一旦這個過程完成后赛惩,還有一些在GPU上發(fā)生的可選的階段(stages)哀墓,按此順序:tessellation,geometry shading和流輸出(stream output)喷兼。是否使用由硬件的能力(并不是所有的GPUs都支持)和程序員的意愿決定篮绰。它們之間相互獨立,通常用不到它們季惯。
第一個可選可選的階段是曲面細分/表面細分(tessellation)吠各。設(shè)想你有一個彈球,如果你用一個單獨的三角形集合(a single set of triangles)來表示它勉抓,你可能會遇到質(zhì)量或性能問題贾漏。你的球可能在5米遠處看起來挺好的蔓纠,但是一旦靠近祟剔,就會看到一個個三角形夷都。如果你使用更多的三角形來提高球的渲染質(zhì)量乳蛾,當球離相機遠只覆蓋屏幕上一點點像素的時候,你可能會浪費相當大的處理時間和內(nèi)存橄镜。通過曲面細分(tessellation)可以使用適量個數(shù)的三角形來生成一個彎曲表面(curved surface)蛀缝。
下一個可選階段是Geometry shader萤厅。Geometry shader在時間上先于表面細分(tessellation shader)暇藏,而且相比之下蜜笤,在GPUs上更常見。它和tessellation shader相似叨咖,因為它接收各種類型的基本體(primitives瘩例,比如點啊胶、線甸各、面),然后可以產(chǎn)生新的頂點(vertices)焰坪。想像一下模擬煙花爆炸趣倾。每個火球可以用一個點(a single vertex)來表示。Geometry shader可以接收每一個點某饰,把它轉(zhuǎn)變成一個面向觀察者儒恋、覆蓋一些像素的正方形(由兩個三角形組成),提供了一個能令人更加信服的用于著色的基本體黔漂。
最后可選一個階段被叫做stream output诫尽。這個階段允許把GPU處理一個幾何引擎(geometry engine)。這個階段不是把處理過的頂點數(shù)據(jù)沿著渲染管線繼續(xù)向下傳送渲染到屏幕上炬守,而是可以選擇(optionally)把這些數(shù)據(jù)輸出到一個數(shù)組中用于進一步處理牧嫉。這些數(shù)據(jù)可以被CPU或GPU使用。這個stage通常被用于粒子模擬,如煙花的例子酣藻。
這三個階段按這樣的順序執(zhí)行: tessellation, geometry shading, stream output曹洽,而且每一個都是可選的。每哪一個被使用了辽剧,如果我們沿著渲染管線走送淆,我們得到的齊次坐標下的頂點集,這將會被用于檢測相機是否可以看到它們怕轿。
Clipping
Primitives(點偷崩、線、三角形撤卢,這里裁剪是對這些基本體進行的)只有在完全或部分出現(xiàn)在視景體(view volume)內(nèi)部時环凿,才能被傳遞到光柵化階段(rasterization stage)以及隨后的像素處理階段(pixel processing stage),才會被繪制到屏幕上放吩。一個完全落在視景體內(nèi)的primitive會按它原有的樣子傳遞到下一個階段智听。完全處于視景體外的Primitives不會被進一步傳遞到下一個階段,因為它們不會被渲染渡紫。只有那些部分落在視景體內(nèi)的物體才會被裁剪到推,這樣會使得視景體外的頂點被新的primitive與視景體相交的點替代。由于使用了投影矩陣惕澎,這意味著這些經(jīng)投影變換后的primitives是相對于一個單位立方體進行裁剪的莉测。在裁剪(clipping)之前,先進行view transformation (從世界空間變換到view space)和投影(projection)的優(yōu)勢是使得裁剪問題具有一致性唧喉,所有primitives總是在一個單位立方體內(nèi)進行的捣卤。Clipping過程如下圖所示。
裁剪這一步(clipping step)使用由投影產(chǎn)生的有四個分量(4-value)的齊次坐標來完成八孝。透視空間中(perspective space)中董朝,坐標不值不是在三角形中進行普通的線性插值。為了在使用透視投影時干跛,數(shù)據(jù)能夠被合理地插值和裁剪子姜,才需要用到第四個坐標值。最后一步是透視除法(perspective division)楼入,這會把三角形放到一個三維的標準化設(shè)備坐標(normalized device coordinates)中哥捕。像之前提到的那樣,這個視景體的坐標值變化范圍是(?1,?1,?1)(?1,?1,?1)到(1,1,1)(1,1,1)嘉熊。在幾何階段(geometry stage)的最后一步是把標準化設(shè)備坐標(空間)標轉(zhuǎn)化到窗口坐標(window coordinates)遥赚。
Screen Mapping
只有經(jīng)裁剪后仍然在視景體內(nèi)部的primitives才會被傳遞到屏幕映射階段(screen mapping stage),且剛進入這一段時的坐標仍然是三維的阐肤。每個primitive的x,y坐標通過變換成為屏幕坐標(screen coordinates)凫佛。屏幕坐標和z坐標一起被稱為窗口坐標(window coordinates)。
三、光柵階段?Rasterization stage
給定變換和投影后的帶有著色數(shù)據(jù)(shading data)的頂點(vertices)(都來自幾何處理階段)御蒲,下一個階段的目標是找到所有在基本體(primitive衣赶,如:點、線厚满、三角形)內(nèi)部的像素(pixels)府瞄。我們稱這個過程為光柵化(rasterization),它被分為兩個功能子階段:三角形設(shè)置(triangle setup碘箍,也稱為圖元裝配遵馆,primitive assembly)和三角形遍歷(triangle traversal),如下圖所示丰榴。這些過程即適用于點(points)货邓、線(lines),也適用于三角形(trangles)四濒,但三角形是最常見的换况,所以了階段用“三角形”來稱這些基本體。
光柵化盗蟆,也叫作掃描轉(zhuǎn)換(scan conversion)戈二,是從屏幕空間的具有z值(即深度值,depth value)和其它著色信息的二維頂點(vertices)到屏幕像素的轉(zhuǎn)換喳资。也可以認為光柵化是幾何處理和像素處理的一個同步點(synchronization point)觉吭,因為由三個頂點(vertices,除了位置坐標仆邓,還包含別的信息鲜滩,紋理坐標,法線)構(gòu)成的三角形是在這里被發(fā)送到像素處理階段的节值。
三角形是否覆蓋某個像素徙硅,由你怎么設(shè)置GPU的渲染管線決定。例如察署,你可能使用點采樣來決定是否在三角形內(nèi)部("insideness")闷游。最簡單的情形是使用在每個像素中心的單點樣本峻汉,這樣如果這個中心點在三角形內(nèi)贴汪,則認為對應(yīng)的像素也在三角形內(nèi)。對于一個像素休吠,你可能使用多于一個采樣點(使用supersampline或multisampling反鋸齒技術(shù))扳埂。另外一種方法是使用保守的光柵化,只要一個像素至少一部分與三角形重疊瘤礁,就認為此像素在三角形內(nèi)("inside")阳懂。
Triangle Setup 三角形設(shè)置
在這個階段differentials, edge equations和此三角形的別的數(shù)據(jù)被計算了。這些數(shù)據(jù)可能用于接下來的三角形遍歷(triangle traversal),和幾何階段產(chǎn)生的各種著色數(shù)據(jù)(shading data)的插值岩调。使用固定功能的硬件來完成這個任務(wù)巷燥。
Triangle Traversal 三角形遍歷
這里是檢測每個像素的中心點(或采樣點)是否被三角形覆蓋了的地方,并且為被三角形覆蓋的部分產(chǎn)生一個fragment号枕。之后缰揪,在第五章會介紹更多的精細復(fù)雜的采樣方法。查找哪些采樣點或像素在三角形內(nèi)部的過程通常稱為三角形遍歷(triangle traversal)葱淳。三角形的每一個fragment的屬性是通過在三角形三個頂點之間進行數(shù)據(jù)插值產(chǎn)生的钝腺。這些屬性包括fragment的深度和所有從幾何階段得到的著色數(shù)據(jù)。這里也是透視校正插值(perspective-correct interpolation)完成的地主赞厕。所有在一個primitive(點艳狐、線、三角形)內(nèi)部的像素或采樣點被送到像素處理階段(pixel processing stage皿桑,見下方)毫目。
四、像素處理階段Pixel Processing
像素處理階段是一個最耗時诲侮,但是也是能使你的渲染效果品質(zhì)更高的地方蒜茴,像素最終的樣子在這一階段決定,可以進行紋理映射浆西、逐像素光照粉私、像素附加處理等,做紋理混合近零、模糊诺核、擴散等效果。這也是可編程管線中使用shader控制的另一個控制過程久信。
Pixel Shading (像素著色)
所有逐像素的著色計算都是在這里完成的窖杀,使插值了的著色數(shù)據(jù)作為輸入。最終結(jié)果是一個或多個將被傳入到下一個階段的顏色裙士。Pixel Shading用可編程的GPU cores完成入客。為此,程序員需要為pixel shader(OpenGL中稱為fragment shader)提供一個程序(里面可以包含任意想要的計算)腿椎。在這兒桌硫,各種各樣的技術(shù)可以被使用,其中最重要的一個是texturing啃炸。簡單地講铆隘,texturing一個物體意味著把一個或多個圖像(images)“融合”("gluing")一物體上。用到的圖像可以是一維的南用、二維的膀钠,甚至三維的掏湾,其中二維的最常見。最終的產(chǎn)出是每個fragment的像素值肿嘲,這些數(shù)據(jù)會被傳遞到下一個子階段融击。
Merging 合并/融合
alpha測試、深度測試雳窟、全局混合等砚嘴。當像素經(jīng)過像素處理階段后,并不能都有機會輸出到屏幕上涩拙,因為他們還要經(jīng)過深度(也有一些比較優(yōu)化的渲染管線將深度測試提到像素處理之前)和模板測試际长、alpha測試,經(jīng)過這些測試后兴泥,還要進行一次alpha混合工育,這次與目標緩沖區(qū)的混合,能夠?qū)崿F(xiàn)半透明的效果搓彻。虛擬世界中的五光十色就是因為這個半透明效果而生動如绸。