天天看點

《Real-Time Rendering 4th Edition》讀書筆記--簡單粗糙翻譯 第二章 渲染管線 The Graphics Rendering Pipeline

寫在前面的話:因為英語不好,是以看得慢,是以還不如索性按自己的了解簡單粗糙翻譯一遍,就當是自己的讀書筆記了。不對之處甚多,以後了解深刻了,英語好了再回來修改。相信花在本書上的時間和精力是值得的。

—————————————————————————————————————————————————————————

“鍊條的堅固程度取決于它最薄弱的環節”

        這章講的是實時渲染的核心内容,圖形渲染管線,通常簡稱為管線。管線的主要功能是通過給定一個虛拟錄影機一些三維物體光源等來生成或渲染出一個二維圖像,是以渲染管線是實時渲染的基礎。圖2.1描述了渲染管線的過程。物體在圖檔中呈現出的位置和形狀由他們的幾何形狀、環境特征以及錄影機在環境中的位置決定。物體的外觀由材質屬性、光源、表面貼圖以及渲染方程決定。

《Real-Time Rendering 4th Edition》讀書筆記--簡單粗糙翻譯 第二章 渲染管線 The Graphics Rendering Pipeline

圖2.1 在左邊的圖中,位于錐形頂端處是一個虛拟錄影機,隻有在錄影機視體裡的圖元才能被渲染。在透視投影(本例所示)中,視體是一個平截頭體。右邊的圖表示的是錄影機看到的内容。注意左邊圖中的紅色甜甜圈形狀的物體并沒有被繪制,因為它位于平截頭體之外。同理左圖中的藍色扭曲棱體超出平截頭體上半部分裁剪掉了。

接下來我們将詳細介紹渲染管線的各階段的功能而不是其實作, 各階段的應用細節将會在後面章節介紹。

2.1  Architecture 架構

       在現實世界中,管線這個概念被應用到了各行各業,例如工廠的生産線、快餐廚房。在圖形渲染管線中,每個階段都有着大量的工作量。

        渲染管線各階段是并行執行的,每個階段又都依賴上一個階段的結果。理想上,一個非管線系統被分成n個管線階段可提高n倍性能。能提高性能是使用管線的主要原因。舉個例子,一部分人一起準備着大量的三明治,一個人負責面包,一個人負責給面包加肉,剩下的人負責給面包加入澆頭。每個人将處理完的三明治交給下一個人進行處理,然後繼續處理下一個三明治。如果每個人需要花費20秒處理完手裡的一個三明治,那麼每個三明治的完成速度最快是20秒,每分鐘3個。雖然管線各階段是并行執行的,但是他們在最慢的階段完成任務之前會被停止。舉例,如果在加肉環節,加入的肉多了,需要花費30秒,那麼一分鐘最快隻能生産2個三明治。對管線而言,加肉階段就是瓶頸,它決定了整個生産過程的速度。加入澆頭階段(消費者一樣)在等待加肉階段完成之前都處于一個饑餓狀态。

        這種結構的管線也應用到了計算機圖形實時渲染環境中。一個粗糙的實時渲染管線被分為4個階段:應用階段,幾何處理階段,光栅化階段和像素處理階段,如圖2.2。這個結構是計算機圖形實時渲染應用程式的核心,也是後續章節讨論内容的基礎。這些階段本身可以成一個管線,可由幾個子階段組成。我們在這裡是按照功能和實作方式區分的。每個階段都有着明确的工作,但是沒有指出工作執行的特定方式。例如一個指定的實作方式是聯合兩個階段為一個單元,或者使用可程式設計核心執行,同時将另外一個更耗時的階段劃分成幾個硬體單元。

《Real-Time Rendering 4th Edition》讀書筆記--簡單粗糙翻譯 第二章 渲染管線 The Graphics Rendering Pipeline

圖2.2 渲染管線的結構粗糙的分成4個階段:應用階段(application)、幾何處理階段(geometry processing)、光栅化階段(rasterization)和像素處理階段(pixel processing)。每個階段本身又可以是一個管線,如幾何階段可以分成幾個子階段,綠色矩形所示;或者如像素處理階段所示,一個階段(或部分)可以平行處理,粉紅色矩形所示。圖中,應用程式階段是一個單一處理過程,但是這個階段也可以分成多個子階段或者多個平行階段。注意光栅化階段是在判定那些像素在一個圖元(例如一個三角形)中。

        渲染速度用每秒多少幀(FPS)來表示,也就是每秒可渲染多少張圖。也可以用赫茲(HZ)來表示,赫茲表示每秒更新的頻率。當然用時間毫秒來表示也行,也就是渲染一張圖所用的時間。生成一張圖所用的時間通常不一樣,取決于每幀的計算複雜度。FPS不僅可表示特定幀的速率,也可以表示一段時間内的平均速率。Hz通常用于硬體,例如螢幕重新整理速率,通常是個固定速率。

        顧名思義,應用階段由應用程式驅動,是以應用階段是應用在運作在一些通用CPU上的軟體程式中。這些CPU通常是多核的,有多線程并行處理的能力。應用階段可利用CPU高效處理大量的工作 。這些工作按程式需求可分為傳統的碰撞檢測、全局加速算法、動畫、實體模拟等等。應用階段下一主要階段是幾何處理階段,這一階段主要是處理變換、投影以及其他的各種類型的幾何處理。在這階段主要是計算什麼被繪制,如何繪制,繪制在哪。幾何處理階段很明顯是應用在圖形處理單元(GPU,擁有很多可程式設計核心)和一些固定操作硬體中。光栅化階段通常是利用三個頂點作為輸入,形成一個三角形,然後找到三角形中所有的像素,然後将這些像素轉發到下一階段。最後,像素處理階段對每一個像素執行一段程式來決定像素的顔色,是否進行深度測試來判斷是否可見,是否和上一個顔色混合出新的顔色。光栅化階段和像素處理階段都是整個階段在GPU中執行。下面四個小節将介紹這四個階段及其子階段。更多關于GPU如何處理這些階段将在第三章詳細說明。

2.2 應用階段

        應用階段通常在CPU上執行,開發者有完全的自主權。因為,開發者可以完全決定它的實作,并可在後期修改來提高它的性能。這一階段的改變對後續階段的性能同樣産生影響。例如,在應用階段的一些算法或者設定可以減少繪制的三角形數。

        一些應用程式的工作可以利用特定的計算着色器在GPU上執行。計算着色器如果忽略其特定的渲染圖形功能,可以看作高度并行的通用處理器。

        在應用階段的最後會将需要渲染的幾何圖形送出給幾何處理階段。這些幾何圖形被稱為渲染圖元,例如點、線和三角形,最後呈現在螢幕上。這也是應用階段最重要的工作。

        如果應用階段是基于軟體實作的話,那麼這一階段沒有像幾何處理階段、光栅化階段、像素處理階段那樣分成了幾個子階段。為了提高性能,這一階段通常利用幾個處理單元處理工作。在CPU設計上,這通常被稱為超标量體系結構,因為他可以同時在工作在幾個處理單元上。8.5章節将會介紹一些利用多處理器單元的方法。

        在應用階段通常會處理碰撞檢測。在兩個物體之間的碰撞被檢測到後,會有對應的處理,例如傳回碰撞的物體及碰撞産生的力回報。在這階段也處理輸入系統,例如鍵盤、滑鼠或頭戴式顯示器。基于這些輸入,不同的處理結果會被執行。還有一些加速算法,例如特定的裁剪算法,一些管線無法處理的工作都會在應用程式階段處理。

2.3 幾何處理階段

        幾何處理階段的主要工作是負責對大部分三角形和頂點的操作。這階段可以劃分成下圖2.3所示的幾個功能階段:頂點着色、投影、裁剪和螢幕映射。

《Real-Time Rendering 4th Edition》讀書筆記--簡單粗糙翻譯 第二章 渲染管線 The Graphics Rendering Pipeline

圖2.3 幾何處理階段按功能可分成的子階段

2.3.1 頂點着色

        頂點着色主要有兩個工作,計算頂點的位置和計算出程式可能需要的頂點資料,例如法線和紋理坐标。以前,大部分物體着色是計算光作用于頂點位置和法線,并将計算後的顔色存儲在頂點。然後這些顔色會插值到三角形。是以,這個可程式設計的頂點處理單元被稱為頂點着色。随着現代GPU的發展,伴随着部分或者全部像素的着色,頂點着色階段越來越簡單,甚至都不需要計算着色方程,這取決于程式的設計者。頂點着色現在越來越友善将資料設定給頂點。例如,頂點着色器可以利用章節4.4和章節4.5中的方法給物體添加動畫。

        我們首先描述計算頂點位置。被呈現到螢幕之前,一個模型被變換到好幾個空間和坐标系中。一開始,模型處在自己的模型空間,這意味着模型沒有進行任何變換。每個模型都可以通過模型變換進行移動和旋轉改變坐标位置和朝向,而且可以多次進行變換。在同一場景中每個模型執行個體可以擁有不同的位置,方向大小而不需要改變模型的基本幾何形狀。

        模型變換其實對模型的頂點和法線進行變換。一個物體的坐标被稱為模型坐标。經過模型變換後,模型可以說處在世界坐标中或者在世界空間中。世界空間是唯一的,每個模型經過各自的模型變換後,都處于世界空間中。

        正如先前提到的,隻有在錄影機看到的模型才會被渲染。錄影機在世界空間中擁有一個位置和方向。為了友善投影和裁剪,錄影機和所有的模型都會經過觀察變換。觀察變換的目的是将錄影機轉換到原點,并設定好它的朝向,錄影機對準的方向是z軸的反方向,y軸向上,x軸向右。我們約定錄影機是朝向-z軸,有些文中設定的是+z軸。這是語義上的不同,對變換而言,從+z軸到-z軸的變換很簡單。經過觀察變換後的實際位置和方向取決于底層的應用程式程式設計接口(API)。觀察變換後的空間可以叫錄影機空間,更常見的是叫觀察空間或者視野空間。圖2.4所示是一個模型經過觀察變換後錄影機和模型的變化。模型變換和觀察變換都需要用到4x4的變換矩陣,這将在第四章講到。然而,意識到頂點和法線能被程式設計計算是很重要的。

《Real-Time Rendering 4th Edition》讀書筆記--簡單粗糙翻譯 第二章 渲染管線 The Graphics Rendering Pipeline

圖2.4 在左邊圖中,是一個自頂向下的視圖,錄影機在世界空間中的位置不再原點,世界空間的+z軸是朝上的。右圖,經過觀察變換後,錄影機的位置在原點,并且錄影機的觀察方向是-z軸,錄影機的x軸朝右,y軸指向螢幕外。這是為了投影和裁剪更簡單更快。圖中藍色區域表示的是視體,這裡用的是透視投影,是以視體是平截頭體。其他類型的投影都是類似的技術。

        接下來,我們描述頂點着色的第二種輸出。為了生成一個足夠現實的場景,隻是渲染出物體的形狀或者頂點是不足夠的,物體的外觀也是需要模仿的。這包括物體的材質以及光照在物體上的反光。從簡單的顔色到細緻實體特征,材質和光可以有多種方式模組化。

        決定一個光在材質上的效果的操作叫着色。它需要計算物體每個頂點上着色方程。有些頂點計算是在幾何處理階段,還有些是在像素處理階段。各種材質資料可以存儲在頂點,例如頂點坐标,法線,顔色以及任何計算着色方程需要的數字資訊。頂點着色生成的資料會被轉送到光栅化階段和像素處理階段,進行插值,計算表面着色。

        在第三章和第五章,以GPU頂點着色器的形式将會更深入的讨論頂點着色。

       作為頂點着色的組成部分,渲染系統需要執行投影和裁剪。将視體轉換到一個極值點為

《Real-Time Rendering 4th Edition》讀書筆記--簡單粗糙翻譯 第二章 渲染管線 The Graphics Rendering Pipeline

《Real-Time Rendering 4th Edition》讀書筆記--簡單粗糙翻譯 第二章 渲染管線 The Graphics Rendering Pipeline

的機關立方體中。體積可以用不同的範圍來定義,例如

《Real-Time Rendering 4th Edition》讀書筆記--簡單粗糙翻譯 第二章 渲染管線 The Graphics Rendering Pipeline

。這個機關立方體被稱為标準化視體。首先是在GPU上的頂點着色器中完成投影,投影有兩種方式,正交投影(又稱平行投影)和透視投影。如圖2.5所示,實際上,正交投影隻是平行投影中的一種,在建築學中可見其他的類型的平行投影,例如三向投影、傾斜投影。

《Real-Time Rendering 4th Edition》讀書筆記--簡單粗糙翻譯 第二章 渲染管線 The Graphics Rendering Pipeline

圖2.5 左邊是正交投影 ,右邊是透視投影

        注意,投影矩陣,通常會和其他的幾何變換組合在一起。

        正交視角的視體通常是一個矩形,經過正交投影後變成一個機關立方體。正交投影的主要特征是平行線經過變換還是平行的。這個變換是由平移變換和縮放變換組合而成。

        透視投影稍微複雜點。在透視投影中,物體裡錄影機越遠,投影後物體變得越小。此外,平行線會在遠方合攏。透視變換模拟了人眼,能感覺到物體大小的變化。在幾何學上,視體稱為平截頭體,就像一個金字塔頭部被截斷了。這個平截頭體同樣需要被轉換成機關立方體中。不管是正交變換還是透視變換,都可以用一個4x4的矩陣表示,模型經過投影變換後,模型會變換到裁剪坐标中。裁剪坐标是一個齊次坐标,将會在第四章讨論到,這裡是沒有除以w的。GPU的頂點着色器必須每次都輸出的是這種類型的坐标,為了確定下一階段,裁剪階段能夠工作正常。

        盡管這些矩陣是把一個體積變換成另外一個體積, 但是他們被稱為投影是因為在後續的生成的圖像中z坐标沒有存儲,而是存儲在了z-buffer中。通過這種方式,模型就從三維空間投影到了二維平面中。

2.3.2  可選的頂點處理

        每個管線都有剛描述到的頂點處理。一旦該頂點處理完成,GPU有幾個可選階段,按照順序:細分曲面(tessellation),幾何着色( geometry shading),流輸出( stream output)。他們需要看硬體是不是支援,并不是所有的GPU都支援,以及看程式是否需要。他們彼此之間互相獨立,通常沒用到。第三章會講述更多細節。

        第一個可選階段是細分曲面。想象一下,你有一個彈跳球對象。如果你隻是用一些列的三角形來描述它,那麼你會面臨一個品質和性能問題。你的球可能在5米外看起來很好,但是仔細觀察每個三角形,特别是輪廓處的三角形,是看得見的。但是一旦你為了提高品質,用更多地三角形來描述球,你可能在離球足夠遠且球在螢幕上隻有幾個像素的時候浪費掉大量的處理時間和記憶體。而細分曲面,可以用适當的三角形表示一個曲面。

        我們已經談了一點三角形,但是到目前為止我們隻是處理了頂點。頂點可以用來表示點、線、三角形或其他的物體。頂點也可以用來表示曲面,例如球。這些表面需要一組控制點(稱為Patch,可以了解為一個很粗糙的曲面)來定義,而每個控制點又由一組頂點構成。細分曲面階段可分成幾個子階段——外殼着色器,細分曲面,域着色器——将這些控制點頂點轉換成更大的頂點集合,然後用這個頂點集合制作出更多地新的三角形。場景中的錄影機用來決定多少三角形需要被制作,當錄影機靠近控制點Patch的時候需要更多地三角形,反之需要的三角形少。

        下一個可選階段是幾何着色器。幾何着色器的出現比細分曲面着色器早,在GPU上幾何着色器要被支援的更多。類似于細分曲面着色器,幾何着色器也是把各圖元的頂點細分歸類,然後生成更多地頂點。這個階段相比細分曲面要簡單的多,因為生成的頂點是有數量限制的,輸出的圖元種類也有更多地限制。幾何着色器有很多的用途,其中最為流行的用法是來生成粒子,比如模拟煙花爆竹的效果。每個火球都可以由一個點,單個頂點來表示。幾何着色器可以把這些點轉變成一個面朝着觀察者的擁有些許像素的正方形以友善進行着色。

        最後一個可選階段是流輸出。這個階段我們可以把GPU當做一個幾何引擎。沒有将我們處理好的頂底輸出給下一個管線階段進而渲染到螢幕,而是選擇輸出這些頂點到一個數組中以便将來用得着。這些資料可以存儲起來,以便被CPU或GPU在未來使用。流輸出最典型的使用是用來模拟粒子,例如煙花。

        可選的三個階段的順序是——細分曲面,幾何着色,流輸出,每一個都是獨立可選的。不管這幾個階段是否被選,渲染管線會繼續走到下一個階段,需要判定生成頂點(坐标是齊次坐标)是否在錄影機視野内。

2.3.3 裁剪

        隻有全部或者部分在視體内的圖元才能被傳給光栅化階段,然後被繪制在螢幕上。如果圖元完全在視體之外,并不會傳給光栅化,是以不會被渲染。對于那些部分在視體内的圖元,需要進行裁剪掉在視體之外的部分。這樣,在視體之外的頂點會被視體和連線相交處的新頂點取代。經過投影矩陣後,意味着圖元是用機關立方體進行裁剪。在裁剪之前執行觀察變換和投影變換的好處是可以簡化裁剪,圖元總是用機關立方體進行裁剪。

        裁剪過程如圖2.6所示。除了視體的6個裁剪面外,還可以自定義額外的裁剪面,818頁處的圖19.1展示了一種自定義裁剪,稱為切割(sectioning)。

        裁剪每步使用的是投影後生成的4值齊次坐标。在透視空間内并不會對三角形進行線性插值。齊次坐标的第4個值在透視投影的時候很重要。最後通過透視除法将三角形的坐标結果轉換到三維規格化裝置坐标中。前面提到的,視體的範圍變成了從

《Real-Time Rendering 4th Edition》讀書筆記--簡單粗糙翻譯 第二章 渲染管線 The Graphics Rendering Pipeline

《Real-Time Rendering 4th Edition》讀書筆記--簡單粗糙翻譯 第二章 渲染管線 The Graphics Rendering Pipeline

。幾何階段的最後一個步驟會将裁剪空間變換到螢幕空間。

《Real-Time Rendering 4th Edition》讀書筆記--簡單粗糙翻譯 第二章 渲染管線 The Graphics Rendering Pipeline

圖2.6  投影變換之後,隻有在機關立方體内的圖元才會進行下一步處理。是以,在機關立方體之外的圖元是會被剔除的,在機關立方體之内的圖元被保留。和機關立方體相交的圖元,相交的交點會變成新的頂點,立方體之外的頂點會被丢棄。

2.3.4 螢幕映射

在視體内的圖元被傳輸到螢幕映射階段,此時的坐标仍然是三維坐标。每個圖元的x軸和y軸被變換為螢幕坐标。螢幕坐标加上z軸被稱為視窗坐标。假設螢幕需要被渲染到視窗中,視窗的左下角坐标為

《Real-Time Rendering 4th Edition》讀書筆記--簡單粗糙翻譯 第二章 渲染管線 The Graphics Rendering Pipeline

,右上角的坐标為

《Real-Time Rendering 4th Edition》讀書筆記--簡單粗糙翻譯 第二章 渲染管線 The Graphics Rendering Pipeline

,有

《Real-Time Rendering 4th Edition》讀書筆記--簡單粗糙翻譯 第二章 渲染管線 The Graphics Rendering Pipeline

《Real-Time Rendering 4th Edition》讀書筆記--簡單粗糙翻譯 第二章 渲染管線 The Graphics Rendering Pipeline

。螢幕映射就是一個縮放的操作。映射後的x,y坐标稱為螢幕坐标,z軸(opengl範圍是[-1,1], directx的範圍是[0,1])同樣被映射到[z1,z2]範圍内,其中z1=0,z2=1是預設值。可以通過API來改變這兩個值。z軸重映射後的螢幕坐标被傳輸到光栅化階段。圖2.7表示了螢幕映射過程。

《Real-Time Rendering 4th Edition》讀書筆記--簡單粗糙翻譯 第二章 渲染管線 The Graphics Rendering Pipeline

圖2.7 投影變換後在機關立方體内的圖元經過螢幕映射後在螢幕上找到對應的坐标位置。

        接下來描述如何通過整數和浮點數關聯到像素點。在笛卡爾坐标系中,給定一組水準像素[0,9],最左邊像素的最邊緣的浮點值坐标為0.0,像素的中心坐标為0.5。是以一組像素[0,9]包含區間為[0,10),公式如下

《Real-Time Rendering 4th Edition》讀書筆記--簡單粗糙翻譯 第二章 渲染管線 The Graphics Rendering Pipeline

d表示像素的索引,是離散的整數,c表示像素點在内的連續浮點數。

        所有的API關于像素位置的坐标都是從左往右遞增的,至于零點坐标是在左上角還是左下角是不一緻的,OpenGL用的是笛卡爾坐标,左下角是零點坐标,而DirectX大部分時候是左上角作為零點的,需要視情況而定。當從一種API移植到另外一種API,考慮到兩者之間的不同很重要。

2.4 光栅化階段

        有了經過變換和投影後的頂點及幾何處理後的相關渲染資料,接下來一個階段的目标就是找到所有需要被渲染的圖元的全部像素,我們稱這個過程為光栅化,它可分成兩個子階段:設定三角形和周遊三角形,如圖2.8所示。注意這些處理也可以處理點和線,之是以子階段名字裡有三角形是因為三角形最為常見。光栅化又叫掃描轉換,是将螢幕空間裡的二維頂點(包含有z值表示深度和頂點相關的各種渲染資訊)轉換到螢幕像素點的過程。光栅化可以認為是幾何處理和像素處理之間的一個同步點,因為這裡構成三角形的頂點由幾何處理得到,同時光栅化後的像素會交給像素處理階段進行處理。

《Real-Time Rendering 4th Edition》讀書筆記--簡單粗糙翻譯 第二章 渲染管線 The Graphics Rendering Pipeline

圖2.8 左邊:光栅化分成兩個子階段,設定三角形,周遊三角形。 右邊:像素處理階段分成兩個階段,像素着色,合并。

        判斷三角形是否覆寫住了像素取決于你如何設定GPU管線。舉個例子,你可能使用點采樣去決定是否在三角形裡面 。最簡單的例子是用一個點采樣像素的中心,如果中心點在三角形内,可以認為該像素在三角形内。你也可以利用多個點來采樣,例如超級采樣supersample或多重采樣multisample抗鋸齒技術。還有一種方式是利用保守光栅化技術,如果像素隻要有一點和三角形重疊,就認為像素在三角形内。

2.4.1 設定三角形

        在這個階段會計算三角形的差異,邊緣方程等資料。這些資料會被用來周遊三角形,插值幾何階段生成的各種着色資料。這個由硬體支援。

2.4.2 周遊三角形

        這裡是檢測每個像素的中心(或采樣點)是否在三角形内,并給在三角形内的像素生成一個片元(fragment)。在5.4章節有更詳細的采樣方法。

       尋找哪些像素或者采樣點在三角形内的過程叫周遊三角形。每個三角形片元的屬性内容都由三角形三個頂點插值而來。這些屬性包括片元的深度,幾何階段生成的着色資料。每個圖元内的像素或采樣點都會傳送給像素處理階段,接下來會講到。

2.5 像素處理階段

        到目前為止,由前面一系列步驟生成的像素的都拿到了。像素處理階段可分成像素着色和合成兩個階段。如圖2.8所示。像素處理階段可以認為是對每個圖元内每個像素或采樣點進行逐像素或逐采樣點計算和操作的地方。

2.5.1 像素着色

        任何逐像素着色計算都在這裡進行,以插值的着色資料作為輸入。輸出到下一階段的是一個或者多個顔色值。不像設定三角形和周遊三角形是由專門的硬體來計算,像素着色階段是由可程式設計的GPU單元執行。程式員提供一段程式給像素着色器(或者片元着色器)。這裡需要用到大量的技術,其中最重要的一項是紋理(texturing)。第六章會詳細講到texturing。簡單說,texturing一個物體就是為了各種各樣的目的給一張或多張圖像添加到物體上。圖2.9展示的是一個簡單的例子。 這些圖像可以是一維、二維、三維圖像,其中二維圖像運用最多。最簡單的了解是經過texturing後會生成每一個片元的顔色值,并會傳送到下一階段。

《Real-Time Rendering 4th Edition》讀書筆記--簡單粗糙翻譯 第二章 渲染管線 The Graphics Rendering Pipeline

圖2.9 左上圖是一個沒有貼圖的巨龍模型  左下圖是添加了各種貼圖後的巨龍模型

2.5.2 合并

        每個像素的資訊都存儲在顔色緩沖(color buffer)中,顔色緩沖是一個顔色值得矩陣(包含紅綠藍三色通道)。合并階段的職責是将由像素着色階段生成的顔色值和目前存儲在顔色緩沖中的顔色進行結合。這個階段又可以稱為ROP(raster operations (pipeline)或 render output unit,取決于你問誰)。不像像素着色階段,GPU子單元處理這個階段不是完全可程式設計的,然而他是可以高度可配的,可生成各種效果。

        這個階段同時也負責解決可見性。這意味着當整個場景被渲染後,顔色緩沖應該包含有所有錄影機能看到的圖元的顔色值。對大部分甚至全部圖形硬體,都是通過z-buffer(又稱深度緩沖)來做這件事的。深度緩沖和顔色緩沖類似,對每個像素而言,他将z值存儲到了離得最近的圖元上。這意味着當一個圖元上的某個像素需要被渲染的時候,需要計算該圖元上該像素的z值并同深度緩沖中目前像素的z值進行比較。如果新計算出來的z值比存儲在深度緩沖中的z值小,則說明目前像素點上的正在渲染的圖元比先前離錄影機最近的圖元更接近錄影機。是以,目前像素的z值和顔色值需要更新。如果計算出來的z值比存在深度緩沖中的z值大,則顔色緩沖和深度緩沖中目前像素點的顔色和z值是不需要改變的。深度緩沖算法是簡單的,複雜度為O(n),其中n是需要渲染的圖元的數量,适用于任何能給相關像素計算z值得圖元。同時注意這個算法運作大部分圖元是無序渲染的,這也是該算法流行的另外一個原因。然而,因為深度緩沖隻存儲了螢幕上每個點的一個單一值,是以它并不能給半透明圖元用。半透明圖元必須在所有不透明圖元渲染之後進行渲染, 并且是從後到前的順序進行,或者使用一個獨立與順序無關的算法(5.5節有講)。透明度是基本z-buffer最主要的幾個缺點之一。

        我們已經說過了顔色緩沖是用來存儲每個像素的顔色值,深度緩沖存儲的是每個像素的z值。然後,還有其他的通道或者緩沖可以用來過濾或抓取片元資訊。和顔色緩沖相關的alpha通道被用來存儲像素的透明度。在舊的API中,alpha通道被用來進行alpha測試選擇性的剔除一些像素。如今,剔除操作可以在像素着色器中完成,并且任何類型的計算都可以觸發剔除。alpha測試可以被用來確定全透明片元不會影響到深度緩沖。

        模闆緩沖是一種離屏緩沖,被用來記錄已渲染的圖元的位置。通常每個像素有8bits。圖檔可以通過各種功能被渲染進模闆緩沖,然後模闆緩沖被用來控制是否渲染進顔色緩沖和深度緩沖。舉例,假設一個圓形區域繪制進模闆緩沖中,就可以利用模闆緩沖隻在圓形區域的圖元能被渲染進顔色緩沖中。模闆緩沖能用來做一些特殊效果。組合階段最後的操作被稱為光栅操作(raster operations ,ROP)或者 混合操作(blend operation)。它可以将三角形内正在處理的像素顔色同顔色緩沖中的顔色進行混合。這可以影響透明度或者顔色樣本的卷積。混合不是完全可程式設計的,而是可配的。然而一些API已經支援光栅順序視圖( raster order views),或者稱為像素着色器可序( pixel shader ordering),使得混合可程式設計。

        幀緩沖通常包含系統中所有的緩沖。

        一旦圖元到達并通過了光栅化階段,那麼這些圖元将被繪制到螢幕上。顔色緩沖中的内容将會繪制到螢幕上。為了避免,觀察者看到圖元正在被光栅化的過程,産生了雙緩沖技術。這意味着場景會被離屏渲染進後緩沖中,一旦場景被渲染完成,後緩沖會被交換到前緩沖,然後呈現到螢幕上。這個交換發生在垂直回掃(vertical retrace)中(垂直同步),這是為了安全 (防止出現閃爍斷層等現象)。

繼續閱讀