DirectX12 3D 遊戲開發與實戰第五章內容

#渲染流水線算法

##學習目標:數據結構

  1. 瞭解用於在2D圖像中表現出場景立體感和空間深度感等真實效果的關鍵因素
  2. 探索如何用Direct3D表示3D對象
  3. 學習如何創建虛擬攝像機
  4. 理解渲染流水線,根據給定的3D場景的幾何描述,生成其2D圖像的流程

##5.1 3D視覺即錯覺? 一、從視覺觀察效果來看,平行線最終會相交於一點(消失點,又稱爲滅點),所以咱們能夠得出結論:隨着深度(z方向)的增長,物體會顯得愈來愈小、(dx是左手座標系,OpenGL是右手座標系)。函數

二、咱們都知道物體重疊,這是一個重要的概念,即不透明的物體能夠遮擋住其後側物體的局部或總體,它傳達了不一樣物體在場景中的深度順序關係工具

三、光照和陰影的處理在刻畫3D物體的實體形狀和立體感中扮演着相當重要的角色,其中陰影擔負着兩個重要的任務,即暗示了光源在場景中的相對位置和物體相對於某物的大概位置。學習

##5.2 模型的表示 實際上,實體3D對象是藉助三角形網格來近似表示的,三角形是3D物體建模的基石,咱們能夠用三角形網格模擬出任何真實世界中的3D物體。固然,點和線也是必不可少的,例如,咱們能夠用一系列寬度爲1像素的線段繪製出一條近似曲線。測試

在遊戲開發的過程當中,咱們通常都不會本身手動列出三角形來模擬3D物體,這樣太累了,通常來講,除了最簡單的模型,咱們大部分模型都是在3D建模工具(3D )中完成。在遊戲開發中流行的建模軟件有:3D Studio Max、LightWave 3D、Maya、Softimage和Blender。動畫

##5.3 計算機色彩基礎 計算機顯示器中每個像素髮出的顏色都是紅綠藍三色混合光,當混合的光線進入觀察者眼中,照射到視網膜的特定區域時,視錐細胞便受到刺激產生神經衝動,並經過視神經傳到大腦,大腦繼而解釋傳來的信號並感知顏色。由於混合光的變化各異,因此細胞受到的刺激也不盡相同,因此咱們就能感知到不一樣顏色間的差別了編碼

每款顯示器能發出的紅綠藍三種顏色的強度是有限的,爲了便於描述光的強度,咱們一般將它量化爲範圍在0-1歸一化區間中的值,0表明無強度,1表明最強的強度,由此咱們可使用3D向量(r,g,b)來表示顏色,這三個份量分別表示紅綠藍三色光在混合光中的強度spa

##5.3.1 顏色運算 略code

##5.3.2 128位顏色 事實上,咱們一般會使用到一種名爲alpha份量(alpha component)的顏色份量,alpha份量經常使用於表示顏色的不透明度(0.0表示徹底透明,1.0表示徹底不透明),它在混合技術中將會起到相當重要的做用。加上這個份量以後,咱們即可以使用4D向量(r,g,b,a)來表示每一種顏色

爲了使用128位數據來表示一種顏色,每個份量都要使用浮點值。因爲每一種顏色均可以使用4D向量來表示,因此咱們在代碼中可使用XMVECTIR類型來描述他們,而後經過DriectXMath向量函數來進行顏色運算。所以咱們也能夠藉助SIMD技術加快數據的處理速度。

##5.3.3 32位顏色 爲了用32位數據表示一種顏色,每個份量盡能夠分配到一個字節,所以每個佔用8位字節的顏色份量就能夠分別描述256中不一樣的顏色強度(0表明無強度,256表明最強強度),這樣四個顏色份量一共能夠產生255的四次方種顏色,在DirectXMath庫中提供了XMCOLOR結構體來存儲32位顏色。

128位顏色和32位顏色之間是能夠相互轉換的,只要將32位顏色向量的每個份量值/255就能夠獲得對應的128位顏色向量。因爲在XMCOLOR中一般將4個8位顏色份量封裝成一個32位整數值(例如一個unsigned int類型的值),所以在32位顏色和128位顏色之間的轉換一般要進行一些額外的運算,對此,DirectXMath庫提供了一個獲取XMCOLOR類型實例而且返回對應的XMVECTOR類型值的函數:

XMVECTOR XM_CALLONV PackedVector::XMLoadColor(const XMCOLOR* pSource);

除此以外,DirectXMath庫還提供了一個能夠將XMVECTOR類型值轉換成XMCOLOR類型值的函數:

void XM_CALLCONV PackedVector::XMStoreColor(XMCOLOR pDestination, FXMVECTOR V);

128位顏色一般用於高精度的顏色運算,例如位於像素着色器內的各類運算。不過最終存儲在後臺緩衝區中的顏色通常都是32位顏色。

##5.4 渲染流水線概述 渲染流水線:若給出某一個3D場景的幾何描述,並在其中放置一臺具備肯定位置和朝向的虛擬攝像機,那麼渲染流水線則是以此攝像機爲觀察視角而生成的2D圖像的一系列步驟

先上圖:

圖片爲手機拍攝,望見諒(圖片來源:DirectX 12 3D 遊戲開發實戰)

上圖中左側表示的是組成渲染流水線的全部階段,右側則是顯存資源,從資源內存池指向渲染目標流水線階段的箭頭表示該階段能夠讀取資源並能夠以資源做爲輸入,從渲染流水線指向資源內存池的箭頭則表示該階段能夠向GPU資源寫入數據。接下來咱們將詳細介紹渲染流水線每個階段。如咱們所見,大多數階段能夠進行讀取資源的操做,可是隻有少部分階段才能夠對GPU資源進行寫操做。(渲染流水線中每個階段所輸出的數據每每都是下一個階段的輸入)

  1. 輸入裝配器階段(從顯存讀取資源,而後將資源裝配成幾何圖元)
  2. 頂點着色器階段(處理裝配完畢的圖元的頂點數據)
  3. 外殼着色器階段(略)
  4. 曲面細分階段(增長三角形網格數量,該階段爲可選階段)
  5. 域着色器階段(略)
  6. 幾何着色器階段(後續再進行介紹,該階段爲可選階段)
  7. 流輸出階段(略)
  8. 光柵化階段(計算三角形對應的像素顏色)
  9. 像素着色器階段(根據光柵化階段計算的結果(即頂點屬性插值)爲每個像素添加顏色)
  10. 輸出合併階段(對像素片斷進行篩選,而後把像素片斷寫入後臺緩衝區)

5.5 輸入裝配階段

輸入裝配器會從顯存中讀取幾何數據(頂點和索引(vertex and index)),再將它們裝配成幾何圖元。這些概念咱們將會在後面陸續進行介紹

##5.5.1 頂點 在數學上,三角形的頂點是兩條邊的交點,線段的頂點是它的兩個端點,對於單個的點來講,它自己就是一個頂點

在Direct3D中,頂點不只能夠用來表示位置信息,還能夠包含其餘的信息。例如:咱們將在第八章爲頂點添加法向量依次來實現光照效果,在第九章中咱們會爲頂點添加紋理座標從而實現紋理貼圖。Direct3D爲用戶自定義頂點格式提供了很高的靈活性,在第六章咱們會講解一些和頂點有關的代碼

##5.5.2 圖元拓撲 在Direct3D中,咱們要經過一種名爲頂點緩衝區的特殊數據結構來將頂點和渲染流水安綁定在一塊兒,頂點緩衝區利用連續的內存來存儲一系列頂點,可是僅憑頂點緩衝區是沒法說明這些頂點將如何組成幾何圖元,所以咱們須要指定圖元拓撲(primitive topology)來告知Direct3D要以何種方式來表示幾何圖元。

void ID3D12GraphicsCommandList::IASetPrimitiveTopology{
D3D_PRIMITIVE_TOPOLOGY PrimitiveTopology
};

typedef enum D3D_PRIMITIVE_TOPOLOGY {
	D3D_PRIMITIVE_TOPOLOGY_UNDEFINED = 0,
	D3D_PRIMITIVE_TOPOLOGY_POINTLIST = 1,
	D3D_PRIMITIVE_TOPOLOGY_LINELIST = 2,
	D3D_PRIMITIVE_TOPOLOGY_LINESTRIP = 3,
	D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = 4,
	D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = 5,
	D3D_PRIMITIVE_TOPOLOGY_LINELIST_ADJ = 10,
	D3D_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ = 11,
	D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST = 12,
	D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = 13,
	.
	.
	.
	D3D_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST = 64,
}D3D_PRIMITIVE_TOPOLOGY;

在用戶經過命令列表修改圖元拓撲以前,全部的繪製調用都會沿用當前設置的圖元拓撲,下面將舉一個經過命令列表對圖元拓撲進行修改的代碼示例:

//經過三角形列表的方式來繪製對象
mCommandList->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

##5.2.2.1 點列表 經過枚舉項D3D_PRIMITIVE_TOPOLOGY_POINTLIST來指定點列表,當使用該圖元拓撲時,全部的頂點都將在繪製過程當中繪製成一個單獨的點

##5.2.2.2 線條帶 經過枚舉項D3D_PRIMITIVE_TOPOLOGY_LINESTRIP來指定線條帶,當使用該圖元拓撲時,頂點將會在繪製調用的過程當中被繪製成一系列連續的線段,因此在這種模式下,n + 1個頂點就會生成n條線段

##5.2.2.3 線列表 經過枚舉項D3D_PRIMITIVE_TOPOLOGY_LINELIST來指定線列表,當使用該圖元拓撲時,頂點在繪製調用時會被繪製成一系列單獨的線段,因此在這種模式下,2n個頂點就會生成n條線段

##5.2.2.4 三角形帶 經過枚舉項D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP來指定三角形帶,當使用該圖元拓撲時,頂點在繪製調用時會被繪製成一系列連續的三角形,因此在這種模式下,n個頂點能夠生成n - 2個三角形(三角形帶的繞序爲爲順時針方向)

##5.2.2.5 三角形列表 經過枚舉項D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST來指定三角形列表,當使用該圖元拓撲時,頂點在繪製調用時會被繪製成一系列獨立的三角形,因此在這種模式下,3n個頂點就會生成n個三角形

##5.2.2.6 具備鄰接數據的圖元拓撲 略

##5.2.2.7 控制點面片列表 D3D_PRIMITIVE_TOPOLOGY_N_CONTROL_POINT_PATCHLIST拓撲類型表示:將頂點數據解釋爲具備N個控制點(control point)的面片列表,(此圖元經常使用與渲染流水線的曲面細分階段,此階段爲可選階段),這種圖元拓撲類型咱們將會在第十四章再次進行討論

##5.5.3 索引 在前面咱們提到過,三角形是3D實體對象的基本組成部分,因此爲三角形指定頂點順序是十分重要的工做,咱們把這個順序稱之爲繞序。

構成3D物體的不一樣三角形之間會共用許多頂點,好比一個四邊形,從數學上來看它只有四個頂點,可是在Direct3D中,繪製一個四邊形必需要使用兩個三角形,即有六個頂點,若是不重複利用頂點數據,那麼咱們須要建立六個頂點(其中有兩個頂點數據是重複的)來繪製一個四邊形,這明顯不是咱們但願看到的結果,因此咱們通常都會藉助三角形帶或者是索引來解決這個問題

三角形帶:藉助三角形帶能夠改善頂點數據的重複建立問題,由於三角形帶圖元拓撲可使頂點在繪製調用的過程當中繪製成一系列連續的三角形。但若是想使用三角形帶改善這個問題,前提是這些幾何體必須是可以組織成帶狀的

索引:這是咱們推薦的解決方法,整個工做流程是這樣的:

  1. 先建立一個頂點列表和索引列表
  2. 在頂點列表中收錄一份全部獨立的頂點,並在索引列表中存儲頂點列表的索引值
  3. 這些索引定義了頂點列表中的頂點是如何組合在一塊兒的,從而構成三角形

經過以上的操做,咱們就把「複用的頂點數據」轉換爲索引列表了,這樣即可以對一個頂點數據進行屢次調用。

##5.6 頂點着色器階段 待圖元被裝配完畢以後,其頂點會被送到頂點着色器階段(vertex shader state),咱們能夠把頂點着色器當作一種輸入數據和輸出數據都是單個頂點的函數,每個要被繪製的頂點都必需要通過頂點着色器的處理以後才能夠送日後續階段。事實上,咱們能夠認爲在硬件中執行的是下列處理操做

for (UINT i = 0; i < numVertices; ++i)
{
	outputVertex[i] = VertexShader(intputVertex[i]);
}

其中的頂點着色器函數(VertexShader)就是咱們要實現的部分,因爲這個階段的操做是由GPU完成的,因此通常速度都會很快

在後續的章節中,咱們會看到各類不一樣的頂點着色器示例,因此在學習完本書以後,咱們應該要對頂點着色器能夠時間的具體功能有一個深入的認識。接下來,咱們將介紹幾種經常使用的空間變換

##5.6.1 局部空間和世界空間 設想:若是咱們正在拍一部電影,咱們所在的團隊須要爲一些特效鏡頭打造一個和火車有關的微縮場景,其中咱們的具體任務是製做一架袖珍小橋,固然,咱們不會把小橋直接搭建在場景之中,不然咱們便須要在一個極其複雜的環境中當心翼翼的工做,以防止破壞場景中的其餘物體,一旦失手便會功虧一簣,相對來說,咱們更加願意在遠離場景的工做室內製做這個袖珍小橋,等製做完成以後在將它以恰當的角度放在場景中合適的位置

3D美工在工做的時候也和上述設想同樣,他們不會直接在世界座標系(世界空間)中直接構建物體的幾何形狀,而是選擇在相對於局部座標系(局部空間)來建立物體。只要在局部空間定義了3D模型的各頂點,咱們就能將它變換到世界空間中,爲了作到這一點,咱們必需要定義局部空間和世界空間二者之間的聯繫。具體的作法是:根據物體的位置和朝向,指定其局部空間座標系的原點和每一個座標軸相對於世界座標系的座標,再運用座標變換便可將物體從局部空間轉換到世界空間了。將局部座標系內的座標轉換到世界座標系中的過程稱爲世界變換,所使用的矩陣稱爲世界矩陣,因爲場景中,每個物體的朝向和位置均可以各不相同,所以它們都會有屬於本身特定的世界矩陣。

在每個3D模型各自的局部座標系中的優勢以下: 一、易於使用,在局部座標系中定義物體能夠很輕鬆的肯定各個頂點的座標

二、物體應該要能夠跨越多個場景重複使用,若是將物體座標相對於某一個特定場景進行硬編碼則會多出不少麻煩

三、咱們有時候須要在同一場景中繪製多個同一物體,可是它們的位置、方向和大小不同,將物體繪製在局部空間能夠解決這個問題。(咱們一般將存儲一份幾何體相對於其局部空間的副本,接着按需求次數來繪製該物體,並使用不一樣的世界矩陣來指定物體在世界空間中的位置、大小和方向,這種方法稱爲實例化)

通常來講,爲了構建一個世界矩陣,咱們必需要弄清局部空間中原點和各座標軸相對於世界空間的座標關係,但實際上,獲取這個關係並不容易並且也不直觀,因此咱們通常採用一種更直觀的方式:定義一系列的變換組合W,即W = SRT;

S:縮放矩陣,將物體縮放到世界空間

R:旋轉矩陣,用來定義物體在局部空間相對於世界空間的朝向

T:平移矩陣,定義的是物體在局部空間相對於世界空間的位置

經過定義一系列的變換組合W,即可以在不指明局部空間的原點以及各座標軸相對於世界空間的齊次座標的狀況下,直接經過複合一系列簡單的變換來創建世界矩陣

##5.6.2 觀察空間 爲了構建場景的2D圖像,咱們必須在場景中架設一臺虛擬攝像機,該攝像機肯定了觀察者能夠見到的視野,也就是生成2D圖像所須要的場景空間範圍,因此咱們要爲該攝像機賦予一個局部座標系,該座標系稱爲觀察座標系,也稱爲觀察空間。虛擬攝像機會位於觀察座標系的原點,而且朝z軸的正方向進行觀察,y軸位於攝像機的上方,x軸位於攝像機的右側(dx使用左手座標系,OpenGL使用右手座標系)。觀察空間用於在渲染流水線後續階段描述這些頂點相對於觀察座標系的位置,由世界空間到觀察空間的座標變換稱之爲觀察變換(視圖變換),所使用的矩陣稱爲觀察矩陣

假設矩陣w爲物體從觀察空間轉換到世界空間的變換矩陣,則從觀察空間轉換到世界空間的變換矩陣V = W的逆矩陣。

接下來咱們將介紹一種構建觀察矩陣的直觀方法:

假設Q爲攝像機的位置,T爲被觀察的目標點的座標,j表示世界空間y軸方向的單位向量,則

觀察座標系的z軸方向的單位向量w爲:(T - Q) / ||T - Q||

觀察座標系的x軸方向的單位向量u爲:(j x w) / ||j x w||

觀察座標系的y軸方向的單位向量v爲:w x v

綜上所述,只有給定攝像機的位置,觀察目標點以及世界空間中y軸方向的向量,就能夠構建出該世界空間對應的觀察空間的觀察矩陣,DirectXMath庫針對上述計算觀察矩陣的方法提過了一個函數:

//輸出對應的觀察矩陣
XMMATRIX XM_CALLCONV XMMatrixLookAtLH(
	FXMVECTOR EyePosition,				//輸入虛擬攝像機的位置
	FXMVECTOR ForcusPosition,			//輸入觀察目標點的位置
	FXMVECTOR UpDriecttion				//輸入世界空間向上方向的向量
)

##5.6.3 投影和齊次裁剪空間 前一節咱們介紹了攝像機在世界空間的位置和朝向,除此以外,虛擬攝像機還有一個重要的組成要素,那就是攝像機能夠觀測到的空間體積(volume of space),此範圍能夠用一個由四棱錐截取的平截頭體(四棱臺)表示。因此咱們的下一個任務即是將平截頭體內的3D幾何體投影到2D投影窗口中,根據前文的透視投影的原理可知,投影一定會隨着衆平行線匯聚於消失點,其投影的尺寸也將會隨着物體3D深度的增長而變小。

圖片爲手機拍攝,望見諒(圖片來源:DirectX 12 3D 遊戲開發實戰)

##5.6.3.1定義平截頭體 在觀察空間中,咱們能夠經過近平面n(near plane)、元平面f(far plane)、垂直視場角a(vertical field of view Angle)以及投影窗口的縱橫比r這四個參數來定義一個以原點爲中心,而且沿z軸正方向進行觀察的平截頭體。接下來咱們將介紹這四個參數的意義:

圖片爲手機拍攝,望見諒(圖片來源:DirectX 12 3D 遊戲開發實戰)

一、近平面n:如圖

二、遠平面f:如圖

三、垂直視場角a:如圖

四、投影窗口的縱橫比r:投影窗口實際是就是觀察空間中場景的2D圖像,因爲該圖像最終將會被映射到後臺緩衝區中,所以,咱們但願投影窗口和後臺緩衝區二者的縱橫比保持一致,因此咱們一般把投影窗口的縱橫比指定爲後臺緩衝區的縱橫比。假如後臺緩衝區的大小爲800 x 600,則投影窗口的縱橫比爲800 / 600。

下面還有不少內容:略

##5.6.3.2 投影頂點 略

##5.6.3.3 規格化設備座標 略

5.6.3.4用矩陣來表示投影公式

##5.6.3.5 歸一化深度值 略

##XMMatrixPerspectiveFovLH函數 咱們能夠利用DirectXMath庫裏的XMMatrixPerSpectiveFovLH函數構建對應的投影矩陣

//構建投影矩陣
XMMATRIX XM_CALLCONV XMMatrixPerspectiveFovLH(
	float FovAngleY,			//用弧度製表示的垂直視場角
	float Aspect,				//投影窗口的縱橫比(通常都與後臺緩衝區的縱橫比相等)
	float NearZ,				//虛擬攝像機的位置(觀察點)到近平面的距離
	float FarZ					//虛擬攝像機的位置(觀察點)到遠平面的距離
);

下面的代碼片斷爲XMMatrixPerspectiveFovLH函數構建一個對應垂直視場角爲45度,近平面位於z = 1.0f,遠平面位於z = 1000.0f的平截頭體的投影矩陣的用法:

XMMATRIX p = XMMatrixPerspectiveFovLH(0.25*XM_PI, AspectRatio(), 1.0f, 1000.0f);

縱橫比採用的是咱們窗口的寬高比:

float D3DApp::AspectRatio()const
{
	return static_cast<float>(mClientWidth / mClientHeight);
}

##5.7 曲面細分階段 曲面細分階段(tessellation stage)是利用鑲嵌化處理技術對網格中的三角形進行細分,以此來增長物體表面的三角形數量。而後將這些三角形偏移到合適的位置,就可使網格展示出更加細膩的細節。使用曲面細分的優勢主要有如下幾方面:

  1. 藉此實現一種細節層次機制。咱們可使距離虛擬攝像機較近的三角形進行鑲嵌化處理,距離虛擬攝像機較遠的三角形則不進行處理
  2. 咱們能夠在內存中僅維護低模(低精度模型)網格,再根據需求爲它動態添加三角形,以此節省內存資源
  3. 咱們在處理動畫和物理模擬的時候可使用簡單的低模網格,而僅在渲染的過程當中使用經鑲嵌化處理的高模網格

曲面細分是一個可選的渲染階段,咱們將在第十四章對此階段進行詳細的講解。

##5.8幾何着色器階段 幾何着色器階段是一個可選的渲染階段,因爲咱們在第十二章纔會用到它,因此咱們這裏只對它進行簡單的介紹。

  1. 幾何着色器接受的輸入必須是完整的圖元,假設咱們正在繪製三角形列表,那麼向幾何着色器輸入的必定是定義三角形的三個頂點(這三個頂點已經被頂點着色器處理過的)
  2. 幾何着色器的主要優勢是能夠銷燬和建立幾何體,好比說,咱們能夠利用幾何着色器將輸入的圖元擴展稱爲一個或多個圖元,或者是根據一些條件而選擇不輸出任何圖元
  3. 頂點着色器與幾何着色器相比,頂點着色器不能建立頂點,它只能接受單個頂點的輸入,而後將處理後的單個頂點輸出。幾何着色器的拿手好戲是將一個點或者一條線擴展成一個四邊形

##5.9 裁剪 徹底位於視椎體(用戶在3D空間內的可視範圍,形狀相似於平截頭體,視椎體也被稱爲視平截頭體)以外的幾何體須要被徹底拋棄,而處於視平截頭體交界的幾何體也要接受此裁剪的操做。所以,只有在視平截頭體以內的物體對象纔會被徹底保留下來。

因爲裁剪操做是由硬件負責完成的,咱們在這裏並不會進行過多的講解,若是對裁剪過程有興趣的話,能夠了解一下蘇澤蘭-霍啓曼裁剪算法,這個算法的總體思路是找到平面和多邊形的全部交點,而後將這些頂點按順序組織成新的裁剪多邊形。

##5.10 光柵化階段 光柵化階段(rasterization stage)的主要任務是爲投影到主屏幕上的3D三角形計算出相應的像素顏色

##5.10.1 視口變換 當裁剪操做完成以後,硬件會經過透視除法將物體從齊次裁剪空間變換到規格化設備座標(NDC),一旦物體的頂點位於NDC空間以內,構成2D圖像的2D頂點x,y座標就會被變換到後臺緩衝區中稱爲視口的矩形之中,此變換完成會後,這些x,y座標都會以像素爲單位進行表示。(通常來講,因爲z座標常常在深度緩衝技術裏面用做爲深度值,因此視口變換通常都不會影響到z座標)

##背面剔除 每個三角形都有兩個面,在Direct3D中會採用如下約定對這兩個面進行區分,假設組成三角形順序的頂點爲v1,v2,v3,那麼咱們會經過如下計算來獲得這個三角形的法線:

e1 = v2 - v1;

e2 = v3 - v1;

n = (e1 x e2) / (||e1 x e2||)

法向量由正面射出,則另外一面爲三角形的背面。在這種約定之下,根據觀察者的視角看過去,頂點繞序爲順時針方向的爲正面朝向,頂點繞序爲逆時針方向的位背面朝向。因爲背面朝向的三角形都會被正面朝向的三角形遮擋,因此繪製背面朝向的三角形是沒有意義的,背面剔除就是用於將背面朝向的三角形從渲染流水線中剔除的流程,這種操做能夠將待處理的三角形數量減小一半。

在默認的狀況下,Direct3D將以觀察者的視角把順時針繞序的三角形看做是正面朝向的,把逆時針繞序的三角形視爲是背面朝向的,可是,經過對Direct3D渲染狀態的設置,咱們也能夠把這個約定顛倒過來。

##5.10.3 頂點屬性插值 回顧前文可知,咱們要經過頂點來定義三角形,除了位置信息以外,咱們還能夠給頂點附加顏色、法向量、紋理座標、深度值等其餘屬性,通過視口變換以後,咱們須要爲求取三角形內每個像素所附的屬性進行線性插值運算,爲了獲得屏幕空間中各個頂點的屬性插值,咱們通常都會使用一種名爲透視校訂插值。從本質上來講,插值法即利用三角形的三個頂點屬性值計算出其內部像素的屬性值

咱們無需考慮透視校訂插值法處理像素屬性的數學細節,由於硬件會自動的完成相應的處理,若是有人對其中的數學細節感興趣。能夠在[Eberly01]中找到相應的數學推導過程

##5.11 像素着色器階段 咱們編寫的像素着色器(pixel shader)是一種由GPU執行的程序,他會針對每個像素片斷進行處理(即每處理一個像素都要執行一次像素種着色器),並根據頂點的插值屬性做爲輸入來計算出對應的像素顏色。像素着色器既能夠返回一種單一的恆定顏色,也能夠實現如逐像素光照、反射以及陰影等更爲複雜的效果。

##5.12 輸出合併階段 經過像素着色器生成的像素片斷會被移送至渲染流水線的輸出合併階段,在此階段,一些像素片斷可能會被丟棄(好比未經過深度測試或模板測試的像素片斷)。而沒有被丟棄的像素片斷則會被寫入後臺緩衝區。

混合操做也是在輸出合併階段完成的,這項技術可使當前處理的像素片斷與後臺緩衝區中原有的像素片斷進行融合,而不是簡單的對後臺緩衝區進行覆蓋。

#小結

  1. 根據人們的生活經驗,咱們能夠總結一些規律用於Direct3D中:平行線會相聚於消失點、物體的尺寸受其深度的影響(近大遠小)、離觀察者近的物體會遮擋其後距觀察者遠的物體、光照和陰影的明暗對比能夠刻畫出3D物體的實體形狀和體積感、陰影還暗示了光源的位置以及場景中不一樣物體之間的相對位置
  2. 咱們用三角形網格來近似的表示3D物體對象,並經過指定三角形的3個頂點來定義三角形,在許多網格中都存在着頂點被不一樣三角形共用的狀況,而索引列表則能夠用於避免由於重複使用頂點而複製頂點數據所帶來的亢餘信息
  3. 咱們通常經過紅綠藍三色光的強度來描述顏色,利用三色光不一樣強度的相加混色,能夠表示出數以千萬計種顏色。通常來講咱們還會加入一種名爲Alpha份量的顏色份量,這個份量用於表示顏色的不透明度,這在混合技術中是頗有用的。綜上,咱們可使用4D顏色向量來表示四個顏色份量。
  4. 假設在一個場景中有一臺虛擬攝像機,那麼渲染流水線就是根據該虛擬攝像機的視角,生成能呈如今顯示器中對應的2D圖像的一系列完整的步驟
  5. 渲染流水線能夠分爲8個重要階段,分別是:輸入裝配階段、頂點着色器階段、曲面細分階段、幾何着色器階段、裁剪階段、光柵化階段、像素着色器階段、輸出合併階段。
相關文章
相關標籤/搜索