天天看點

圖形渲染管線

一條鍊沒有比其最薄弱的一環更強大   ---匿名 本章介紹了實時圖形的核心元件,即圖形渲染管道,也簡稱為“管道”。 管道的主要功能是在給定虛拟相機,三維對象,光源等的情況下生成或渲染二維圖像。 是以,渲染管道是用于實時渲染的基礎工具。 使用管道的過程如圖2.1所示。 圖像中對象的位置和形狀取決于它們的幾何形狀,環境的特征以及相機在該環境中的位置。 對象的外觀受材質屬性,光源,紋理(應用于表面的圖像)和着色方程式(shading equations)的影響。
圖形渲染管線
圖2.1。 在左圖中,虛拟攝像頭位于金字塔的頂端(四條線彙合處)。 僅渲染視錐體内的圖元。 對于透視渲染的圖像(此處就是這種情況),視圖體積為視錐(複數:視錐),即具有矩形底面的截頂金字塔。 右圖顯示了相機“看到”的内容。 請注意,左側圖像中的紅色甜甜圈形狀不在右側渲染中,因為它位于視錐的外部。 同樣,左圖中扭曲的藍色棱柱也被夾在平截頭錐體的頂平面上。 我們将解釋渲染管道的不同階段,重點是功能而不是實作。 應用這些階段的相關細節将在後面的章節中進行介紹。 在實體(physical)世界中,管道概念以許多不同的形式表現出來,從工廠流水線到快餐店廚房。它也适用于圖形渲染。管道包含幾個階段,每個階段執行較大任務的一部分。流水線階段并行執行,每個階段取決于上一個階段的結果。理想情況下,将非流水線系統分成n個流水線級可以使速度提高n倍。性能提升是使用流水線的主要原因。例如,大量的三明治可以由一系列人迅速準備,一個準備面包,另一個添加肉,另一個添加配料。每個都将結果傳遞給下一個等待的人後,立即開始在下一個三明治上工作。如果每個人花二十秒鐘完成他們的任務,每二十秒最多一個三明治,一分鐘三個是可能的。流水線并行執行,但它們被暫停直到最慢的階段完成任務。舉例來說,添加肉的階段變得更加複雜,耗時三十秒。現在可以達到的最佳效率為一分鐘就能吃到兩個三明治。對于這個特定的管道,添加肉的階段是瓶頸,因為它決定了整個生産的速度。在添加肉的階段完成之前,添加配料的階段将會出現饑餓等待(顧客也是如此)。這種管道構造也可以在實時計算機圖形的上下文中找到。實時渲染流水線大緻分為四個主要部分應用階段,幾何處理,光珊化和像素處理等階段如圖2.2所示。該結構是渲染管道的核心(引擎)。
圖形渲染管線
圖2.2。 渲染管道的基本建構包括四個階段:應用,幾何處理,光栅化和像素處理。 這些階段中的每個階段都可以是本身,如下面的幾何處理階段所示,或者一個階段可以(部分)并行化,例如在像素處理階段下方顯示。 在此示例中,應用程式階段是單個過程,但是此階段也可以流水線化或并行化。 請注意,光栅化會找到内部的圖元像素,例如三角形。 用于實時計算機圖形應用程式,是以在後續章節中進行讨論。 這些階段中的每一個通常本身就是一個管道,這意味着它包含幾個子階段。 我們區分此處顯示的功能階段和其實作的結構。 功能階段具有要執行的特定任務,但未指定任務的執行方式管道。 給定的實作可以将兩個功能階段組合為一個單元或使用可程式設計核心執行,而它又劃分了另一個更耗時的時間,功能階段分為幾個硬體單元。 渲染速度可以以每秒幀數(FPS)表示,即每秒渲染的圖像數。也可以用赫茲(Hz)表示這隻是1秒的表示法,即更新頻率。也是通常隻說明渲染圖像所需的時間(以毫秒(ms)為機關)。生成圖像的時間通常會有所不同,具體取決于圖像的複雜程度。在每個幀中執行的計算。每秒幀數用于表示特定幀的速率或一段時間内的平均性能使用。赫茲用于設定為固定速率的硬體(例如顯示器)。顧名思義,應用程式階段由應用程式驅動,并且是是以通常在通用CPU上運作的軟體中實作。這些CPU通常包括能夠處理多個線程的多個核心并行執行。這使CPU可以高效地運作各種應用階段負責的任務。傳統上在CPU上執行的一些任務包括碰撞檢測,全局加速算法,動畫,實體模拟以及許多其他功能,具體取決于應用程式的類型。下一個主要階段是幾何處理,它處理變換,投影,以及所有其他類型的幾何處理。這個階段計算要繪制的内容,應如何繪制以及應在何處繪制。幾何階段通常是在包含許多可程式設計功能的圖形處理單元(GPU)核心以及固定操作的硬體上執行。光栅化階段通常需要輸入三個頂點,形成一個三角形,并找到所有被視為該三角形内部的像素,然後将其轉發到下一個階段。最後是像素處理階段,每個像素執行一個程式以确定其顔色,并可以執行深度測試看看它是否可見。它還可以執行每個像素的操作,例如将新計算的顔色與以前的顔色混合。光栅化和像素處理階段也完全在GPU上處理。所有這些階段及其内部管道将在接下來的四個部分中讨論。有關GPU如何處理這些階段的内容在第3章中給出。 開發人員可以完全控制應用程式階段發生的事情,因為它通常在CPU上執行。 是以,開發人員可以完全确定實作,以後可以對其進行修改以提高性能。 改變這個階段也會影響後續階段的表現。 例如,應用程式階段算法或設定可能會減少要渲染的三角形數量。 綜上所述,GPU可以使用單獨的應用程式來執行一些應用程式工作。稱為計算着色器的模式。此模式将GPU視為高度并行的通用裝置處理器,而忽略其專門用于渲染圖形的特殊功能。在應用程式階段結束時,将要渲染的幾何圖形輸出到幾何處理階段。這些是渲染圖元,即點,線和三角形,最終可能會出現在螢幕上(或其他任何正在使用的輸出裝置)。這是應用程式階段最重要的任務。此階段是基于軟體實作的結果是不分為子階段,幾何處理,光栅化和像素也是類似的處理階段。但是,為了提高性能,通常執行此階段在多個處理器核心上并行運作。在CPU設計中,這稱為超标量構造(superscalar construction),因為它能夠在同一時間同時執行多個流程階段。第18.5節介紹了使用多個處理器核心的各種方法。在此階段通常實作的一種過程是碰撞檢測。之後在兩個對象之間檢測到碰撞,可能會生成回報并将其發送到撞擊物體以及力回報裝置。應用程式階段也是處理其他輸入來源的地方,例如鍵盤,滑鼠或頭戴式顯示器。根據此輸入,幾種不同類型的措施可能發生。加速算法,例如特定的剔除算法(第19章),以及其餘管道無法處理的。 GPU上的幾何處理階段負責大部分逐三角形和逐頂點的操作。 此階段進一步分為以下功能階段:頂點着色,投影,裁剪和螢幕映射(圖2.3)。
圖形渲染管線
圖2.3。 幾何處理階段分為功能階段的流水線。 頂點着色器主要有兩個任務,計算頂點的位置和輸出一些頂點相關的資料,比如法線和紋理坐标。傳統上,通過将光線應用于每個頂點的位置和法線,僅在頂點在存儲結果顔色。然後對這些顔色以三角形為機關進行插值。是以,這個可程式設計的頂點處理單元是命名為頂點着色器。随着現代GPU的出現,所有的着色都發生在每個像素上,這個頂點着色階段更通用,可能根本不會計算任何着色方程式,這取決于程式員的意圖。現在,頂點着色器是一個更通用的單元,專用于設定與每個頂點關聯的資料。 例如,使用第4.4節和第4.5節中的方法,頂點着色器可以為對象設定動畫。 我們從描述頂點位置的計算方法開始,這是一組坐标,這始終是必需的。在進入螢幕的過程中,模型被轉換成多個不同的空間或坐标系。最初,模型駐留在其自己的模型空間中,這僅僅意味着它根本沒有被改變。每一個模型都可以進行模型變換(model transform)以至于可以平移和旋轉。它可以将多個模型轉換與單個模型轉換相關聯。 這允許同一模型的多個副本(稱為執行個體)具有不同的位置,方向和大小在同一場景中,而無需複制基本幾何體。 模型轉換的是模型的頂點和法線。 對象的坐标稱為模型坐标,在将模型變換應用于這些坐标後,這些模型就被定位在世界坐标或世界空間中。 世界空間是獨一無二的,在模型使用各自的模型轉換之後 ,所有模型都存在于此相同的空間。 如前所述,隻有錄影機(或觀察者)看到的模型是被呈現出來的。相機在世界空間中有一個位置和一個方向,用于放置并對準相機。為了便于投影和裁剪,相機和所有模型使用視圖變換進行變換。視圖轉換的目的是将相機放在原點并對準它,使其朝着負z軸,y軸指向上方,x軸指向右側。我們使用-z軸約定;有些文本更喜歡向下看+ z軸。這差異主要是語義上的,因為彼此之間的轉換很簡單。這應用視圖變換後的實際位置和方向取決于在基礎應用程式程式設計接口(API)上。這樣劃定的空間稱為相機空間,或更常見的稱為視野空間或眼睛空間。一個例子視圖變換影響相機和模型的方式如下所示圖2.4。
圖形渲染管線
圖2.4。 在左圖中,自上而下的視圖顯示了錄影機的位置和方向,如使用者希望它在正Z軸朝上的世界中成為現實。 視圖轉換使世界重新定向讓相機位于原點,沿其負Z軸看,而相機的正 Y軸朝上,如右圖所示。 這樣做是為了使裁剪和投影操作更簡單,更快捷。淺藍色區域是視圖體積(view volume)。 在此,假定是透視圖,因為視圖體積是一個視錐體。 類似的技術适用于任何類型的投影。 模型轉換和視圖轉換都可以實作為4×4矩陣,這是第4章的主題。但是,重要的是要認識到,程式員可以通過以任何喜歡的方式計算頂點的位置和法線。 接下來,我們描述頂點着色的第二種輸出類型。 為了産生一個逼真的場景,僅渲染對象的形狀和位置是不夠的,外觀也必須模組化。 這說明包括每個對象的材質,以及任何光源照在物體上的效果。 材質和燈光以多種方式模組化,從簡單的顔色到複雜的實體描述圖形表示。 光線結合材質決定着效果被稱為着色。它涉及計算對象上各個點的着色方程式。 通常,其中一些計算是在模型的幾何處理期間執行的,頂點和其他頂點可以在逐像素處理期間執行。 每個頂點可以存儲各種材質資料,例如點的位置,法線,顔色,或評估着色方程式所需的任何其他數字資訊。頂點着色結果(可以是顔色,向量,紋理坐标以及任何其他種類的着色資料)然後發送到光栅化和像素處理進行插值并用于計算表面着色的階段。 将以GPU頂點着色器的形式對頂點着色進行更深入的讨論在本書中,尤其是在第3章和第5章中。 作為頂點着色的一部分,渲染系統先進行投影,然後進行裁剪,這會将視圖體積轉換為一個機關立方體,其極點(extreme points)位于(-1,-1,-1)到(1、1、1)之間。 定義相同體積的不同範圍可以并且是例如,0≤z≤1。機關立方稱為規範視圖體積。 首先進行投影,然後在GPU上通過頂點着色器完成投影。 有兩種常用的投影方法,即正交投影(也稱為平行投影)透視投影。參見圖2.5。 實際上,正交投影隻是其中一種平行投影。 還有其他幾個用途,尤其是在建築領域,例如斜投影和軸測投影。 舊的街機遊戲Zaxxon被命名為從後者(from the latter)。
圖形渲染管線
圖2.5。 左側是正交投影或平行投影; 在右邊是一個透視投影 請注意,投影表示為矩陣(第4.7節),是以有時與其餘的幾何變換連接配接在一起。 正交視圖的視圖體積通常是一個矩形框,并且正交投影可将此視圖體積轉換為機關立方體。 正交投影的主要的特點是平行線在轉換後仍然保持平行。 此轉換是平移和縮放的組合。 透視投影有點複雜。 在這種類型的投影中,物體離相機越遠,投影後出現的越小。另外,平行線可能會聚在地平線上。 是以透視變換模仿了我們感覺物體尺寸的方式。 從幾何學上講,視圖體積稱為 截錐體是具有矩形底面的截頂金字塔。 視錐也将轉換為機關立方體。 正交變換和透視變換都可以是用4×4矩陣構造(第4章),并在進行任何變換之後,模型處于裁剪坐标系中。 這些實際上是齊次坐标,已讨論在第4章中,是以發生在用w除之前。 GPU的頂點着色器必須總是輸出此類型的坐标,以便正常進行下一個功能階段的裁剪工作。 盡管這些矩陣将一個體積轉換為另一個體積,但它們被稱為投影,因為在顯示之後,z坐标不會存儲在生成的圖像中,而是存儲在z緩沖區中,如第2.5節所述。 通過這種方式,可以對模型進行從三個次元到兩個次元投影。 每個流水線都有剛剛描述的頂點處理。 完成此處理後,在GPU上可以按此順序進行一些可選階段:細分,幾何體着色和流輸出。 它們的使用取決于功能硬體-并非所有GPU都具有它們-以及程式員的願望。 他們彼此獨立,通常不常用。 更多會在第3章中對每一個都說一遍。 第一個可選階段是細分。 假設您有一個彈跳的球物體。如果用一組三角形表示它,則可能會遇到以下問題:品質或性能。 您的球從5米遠處看起來可能不錯,但近距離各個三角形,尤其是沿輪廓的三角形變得可見。 如果你做帶有更多三角形的球以提高品質,可能會浪費大量的處理時間和記憶體,當球距離很遠并且僅覆寫螢幕上的幾個像素。通過細分,在曲面上可以生成适當數量的三角形。 我們已經讨論了三角形,但是到目前為止,我們已經有了剛剛處理過的頂點。 這些可以用來表示點,線,三角形或其他對象。 頂點可用于描述曲面,例如球。 這樣的曲面可以由一組更新檔(patches)指定,每個更新檔由一組頂點組成。細分階段本身包括一系列階段-殼(Hull)着色器,細分和域着色器-将這些面片頂點集轉換為(通常)較大的集的頂點,然後用于制作新的三角形集。 現場錄影機可用于确定生成了多少個三角形:更新檔很近的時候多,很遠的時候很少。 下一個可選階段是幾何着色器。 該着色器早于曲面細分着色器,是以在GPU上更常見。 就像曲面細分着色器一樣因為它輸入了各種類型的圖元,并且可以産生新的頂點。 它是一個更簡單的階段,因為建立的範圍和輸出類型受到限制的局限性比輸出基礎圖元要大得多。 幾何着色器有多種用途,其中一種最受歡迎的是粒子生成。 想象一下模拟煙花爆炸。 每個火球都可以由一個點,單個頂點表示。 幾何着色器可以将每個點都變成面對它的正方形(由兩個三角形組成)視口(viewer)并覆寫了幾個像素,是以為我們提供了更令人信服的圖元着色。 最後一個可選階段稱為流輸出。 這個階段可以讓我們使用GPU作為幾何引擎。 而不是将處理後的頂點發送到其餘的要渲染到螢幕的管道,這時我們可以選擇将其輸出到用于進一步處理的數組。 這些資料可由CPU或GPU本身使用,在以後的過程中。 此階段通常用于粒子模拟,例如我們的煙花的例子。 這三個階段按以下順序執行:細分,幾何體着色,和流輸出-每個都是可選的。 無論哪個(如果有)選項是使用過的,如果我們繼續沿管線移動,我們會有一組具有齊次坐标的頂點,錄影機視口将會确認它們。 隻要全部或部分包含在視圖區内的圖元到光栅化階段(和随後的像素處理階段),就會在螢幕上繪制它們。完全位于視圖體積内的圖元将照原樣傳遞到下一個階段。圖元完全不在視線範圍内由于未渲染,是以不會進一步傳遞。正是這些圖元部分位于需要裁剪的視圖體積之内。例如,一行視圖體積的外部一個頂點和内部一個頂點應相對于視圖修剪體積,以便将位于外部的頂點替換為位于的新頂點線上條和視圖體積之間的交點處。使用投影矩陣表示将變換後的圖元剪裁在機關立方體上。這在裁剪之前執行視圖轉換和投影的優點是它使剔除問題保持一緻;圖元總是被剪裁在機關立方體裡面。 裁剪過程如圖2.6所示。 除了六個裁剪視區的平面,使用者可以定義其他裁剪平面以明顯地裁剪對象。在第818頁的圖19.1中顯示了這種類型的可視化,稱為“切片”。
圖形渲染管線
圖2.6。 投影變換後,隻有機關立方體内的圖元(對于視錐内部的基本圖元)是需要繼續處理的。 是以,機關立方體外的圖元将被丢棄,而完全内部在内部的圖元将保留。 與機關立方體相交的圖元會被裁剪,進而生成新的頂點并且舊的頂點被丢棄。 裁剪步驟使用投影産生的4值齊次坐标執行裁剪。 值通常不會跨三角形線性插值在透視空間中。 需要第四個坐标,以便在使用透視投影時正确地插值和剪切資料。 最後,透視劃分執行,将生成的三角形的位置放到三維空間中規範化的裝置坐标。 如前所述,該視圖的範圍從(-1,-1,-1)至(1、1、1)。 幾何階段的最後一步是從此轉換到視窗坐标空間。 隻有視圖空間内的(被剪切後)圖元傳遞到螢幕映射階段,并且進入該階段時坐标仍然是三維的。每個圖元的x和y坐标都将轉換為螢幕坐标。螢幕坐标和z坐标也稱為視窗坐标。假定場景應渲染到具有最小拐角的視窗中在(x1,y1)和最大角在(x2,y2)處,其中x1 <x2和y1 <y2。 然後螢幕映射是轉換,後面是縮放操作。 新的x和y坐标被稱為螢幕坐标。 z坐标(對于OpenGL,[-1,+1]并且DirectX的[0,1])也映射到[z1,z2],預設情況下z1 = 0和z2 = 1。 但是,可以使用API進行更改。 視窗沿将此重映射的z值傳遞給光栅化器階段。 螢幕映射處理過程如圖2.7所示。
圖形渲染管線
圖2.7。 在投影變換和螢幕映射之後,圖元位于機關立方體中該過程需要在螢幕上查找坐标。 接下來,我們描述整數和浮點值與像素(和紋理坐标)。 給定水準像素陣列并使用笛卡爾坐标,在浮點坐标中,最左邊像素的左邊緣為0.0。 OpenGL一直以來使用了該方案,DirectX 10及其後續版本使用了該方案。 該像素的中心是在0.5。 是以,像素[0,9]的範圍覆寫了[0.0,10.0)的範圍。 轉換是簡單地
圖形渲染管線