天天看點

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

    渲染管線(rendering pipeline)是指:在給定一個3D場景的幾何描述及一架已經确定位置和方向的虛拟錄影機時,根據虛拟錄影機的視角生成2D圖像的一系列步驟。以下文章将會具體描述這些步驟(階段)。

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

1.輸入裝配階段

    輸入裝配(Input Assembler,簡稱IA)階段從記憶體讀取幾何資料(頂點和索引)并将這些資料組合為幾何圖元(例如三角形和直線)。

1.1頂點

    從數學上來說,三角形的頂點即邊的交點;線段的頂點即端點;點的頂點即為本身。

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

    上圖說明頂點隻是幾何圖元中一個特殊的點。但在D3D中,頂點具有更多含義。本質上,D3D中的頂點有空間位置和各種附加屬性組成。(此處不具體展開了就)。

1.2圖元拓撲

    頂點是以頂點緩沖區(D3D資料結構)的形式綁定到圖形管線的。頂點緩沖區隻是在連續的記憶體中存儲了一個頂點清單。但并不知道這些頂點是如何組織的。是以要通過制定圖元拓撲來告訴D3D以何種方式組成幾何圖元。

void ID3D11Device::IASetPrimitiveTopology(
    D3D11_PRIMITIVE_TOPOLOGY Topology);
typedef enum D3D11_PRIMITIVE_TOPOLOGY
{
    D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED = 0,
    D3D11_PRIMITIVE_TOPOLOGY_POINTLIST = 1,
    D3D11_PRIMITIVE_TOPOLOGY_LINELIST = 2,
    D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP = 3,
    D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST = 4,
    D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP = 5,
    D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ = 10,
    D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ = 11,
    D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ = 12,
    D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ= 13,
    D3D11_PRIMITIVE_TOPOLOGY_1_CONTROL_POINT_PATCHLIST = 33,
    D3D11_PRIMITIVE_TOPOLOGY_2_CONTROL_POINT_PATCHLIST = 34,
    . . .
    D3D11_PRIMITIVE_TOPOLOGY_32_CONTROL_POINT_PATCHLIST = 64,
} D3D11_PRIMITIVE_TOPOLOGY;
           

    以下圖檔為部分圖元拓撲的示例,選擇對應的标志即可選擇使用的圖元。

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段
Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

1.3索引

    先說一個結論,三角形是構成3D物體的基本機關。下面的代碼示範了如何使用三角形清單來建構四邊形和八邊形的頂點數組(每三個頂點構成一個三角形)。

Vertex quad[6] ={
    v0, v1, v2, // Triangle0
    v0, v2, v3, // Triangle1
};
Vertex octagon[24] ={
    v0, v1, v2, // Triangle0
    v0, v2, v3, // Triangle1
    v0, v3, v4, // Triangle2
    v0, v4, v5, // Triangle3
    v0, v5, v6, // Triangle4
    v0, v6, v7, // Triangle5
    v0, v7, v8, // Triangle6
    v0, v8, v1  // Triangle7
};
           

    注意:三角形的頂點順序非常重要,具體會在之後背面消隐的小節中提到。

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

    如上圖所示,構成3D物體的三角形會共享許多相同同的頂點。這在八邊形的V0點表現尤其明顯。複制(重複)頂點的數量會随着模型細節和複雜性的提高而驟然上升。這樣就會浪費大量的資源(記憶體)。

    三角形帶可以在一定程度上解決複制頂點的問題,然而三角形帶組織起來比較麻煩,難度很大。相比之下三角形清單就非常靈活了。如果能找到一種方法,即移除複制頂點,又保留三角形清單的靈活性,就很爽了。而索引就可以解決這個問題。

    它的原理是:建立一個頂點清單和一個索引清單。頂點清單包含所有唯一的頂點,而索引清單包含指向頂點清單的索引值,這些索引定義了頂點以何種方式組成三角形。回顧上圖,四邊形頂點清單可以這樣建立:

Vertex v[4] = {v0, v1, v2, v3};
           

    而索引清單需要定義如何将頂點清單中的頂點放在一起,構成兩個三角形。

UINT indexList[6] = {0, 1, 2, // Triangle0
    0, 2, 3}; // Triangle 1
           

    以上的索引清單含義為:使用頂點v[0],v[1],v[2]構成三角形0,使用頂點v[0],v[2],v[3]構成三角形1。

    與之類似,八邊形的頂點清單和索引清單可以如此建立:

//頂點清單
Vertex v[9] = {v0, v1, v2, v3, v4, v5, v6, v7, v8};

//索引清單
UINT indexList[24] = {
    0, 1, 2, // Triangle 0
    0, 2, 3, // Triangle 1
    0, 3, 4, // Triangle 2
    0, 4, 5, // Triangle 3
    0, 5, 6, // Triangle 4
    0, 6, 7, // Triangle 5
    0, 7, 8, // Triangle 6
    0, 8, 1 // Triangle7
};
           

    總結一下,就是把頂點的複制轉嫁給了索引,而索引都是基本的整數數值類型,就算大量複制也不會使用多少記憶體。而通過适當的頂點緩存排序,圖形硬體也不必重複處理頂點(絕大多數情況下)。

2.頂點着色器階段

    在完成圖元裝配後,頂點将被送往頂點着色器(vertex shader)階段。頂點着色器可以被看成是一個以頂點作為輸入輸出的函數(輸入未經着色的原始頂點,輸出着色後的頂點)。我們可以概念性地認為在硬體上執行了如下代碼。

for(UINT i = 0; i < numVertices; ++i)
    outputVertex[i] = VertexShader(inputVertex[i]);
           

    頂點着色器函數由我們自己編寫,它會在GPU上運作,是以速度非常快。

    許多效果,比如變換(transformation)、光照(lighting)、和置換貼圖映射(displacement mapping)都是由頂點着色器來實作。在頂點着色器中,我們不僅可以通路輸入的頂點資料,也可以通路在記憶體中的紋理和其他資料,比如變換矩陣的場景和燈光。

2.1局部空間和世界空間

    建立3D場景時,我們往往不會在世界坐标系中直接建立物體(這樣太麻煩了,太難了),而是在便于操作的局部坐标系中建立物體。局部坐标系的原點接近于物體中心,坐标軸的方向和物體的方向也是對齊的,是以操作起來會很友善。

    在局部空間(坐标系)中完成物體的建立後,再把它放到(轉換到)世界空間(坐标系)中,這個轉換操作也非常簡單(以下會提到)。當所有物體都從局部空間變換到世界空間,這些物體就位于同一個坐标系(世界坐标系)中了。

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

    根據模型自身的局部坐标系定義模型,有以下幾點好處。

    1.簡單易用,操作友善。坐标系原點通常與物體中心對齊,坐标軸也是對齊的。非常便于描述。

    2.便于在多個場景中複用,不用每次都重新定義。

    3.便于在單個場景中複用,簡單來說執行個體化操作便捷。

    世界矩陣描述的是一個物體的局部空間相對于世界空間的原點位置和坐标軸方向,這些坐标可以存放在一個行矩陣中。

設Qw=(Qx,Qy,Qz,1)、uw=(ux,uy,uz,0)、vw=(vx,vy,vz,0)、ww=(wx,wy,wz,0)分别表示局部空間相對于世界空間的原點、x軸、y軸、z軸的齊次坐标,從局部空間到世界空間的坐标轉換矩陣為:

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

    W=SRT  S R T分别為尺度變化矩陣,旋轉變化矩陣,平移矩陣。

2.2觀察空間

    為了生成場景的2D圖像,我們必須在場景中放置一架虛拟錄影機。虛拟錄影機指定了所要生成的2D圖像所顯示的場景範圍。把一個局部坐标系(觀察空間)附加在錄影機上,該坐标系以錄影機的位置為原點,觀察方向為z軸正方向,右側為x軸,上方為y軸。在渲染管線的後續階段中,使用觀察空間來描述頂點比世界空間要友善得多。從世界空間變換到觀察空間的坐标變換稱為觀察變換,相應的矩陣稱為觀察矩陣。

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

    從觀察空間(本質上也是個局部空間)到世界空間的變換矩陣就是上述的W。因為觀察空間不用考慮尺度變換,故W=RT。顯然,從世界空間轉換到觀察空間的的矩陣就是W的逆矩陣,即V=inv(W)=inv(RT)=inv(T)inv(R)。

    經過簡單的推導,可知觀察矩陣為

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

    現在介紹一種更直覺的方法,通過指定錄影機的位置、目标點和世界“向上”向量來建立錄影機坐标系。

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

學過線代的都知道,顯然有w

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

然後u

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

最後v

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

XNA庫提供了如下函數,根據以上描述計算觀察矩陣。

XMMATRIX XMMatrixLookAtLH(     // Outputs resulting view matrix V
    FXMVECTOR EyePosition,     // Input camera position Q
    FXMVECTOR FocusPosition,   // Input target point T
    FXMVECTOR UpDirection);    // Input world up vector j    
           

    通常,y就是向上的,即(0,1,0)。舉例說明,假設錄影機相對于世界空間的位置為(5,3,-10),目标點為世界原點(0,0,0)。可以使用一下代碼建立觀察矩陣。

XMVECTOR pos = XMVectorSet(5,3,-10,1.0f);
XMVECTOR target = XMVectorZero();
XMVECTOR up = XMVectorSet(0.0f,1.0f,0.0f,0.0f);
XMMATRIXV = XMMatrixLookAtLH(pos,target,up);
           

2.3投影與齊次裁剪空間

    相機可見範圍可通過一個平截頭體(frustum)來描述,如下圖

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

    下一個任務就是把平截頭體内的3D物體投影到2D投影視窗上。将3D頂點v變換到它的投影線與2D投影平面相交的點v'上;我們稱v'為v的投影。對一個3D物體的投影就是對組成該物體的所有頂點的投影。

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

2.3.1定義平截頭體

    可以使用如下參數定義平頭截體:近平面n(與攝像原點距離為n)、遠平面f(與攝像原點距離為f)、垂直視域角α和橫縱比r。

側視圖如下(預設半高為1 即高為2)

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

俯視圖如下

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

可以得到

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

簡單的幾何證明就懶得寫了,學過三角函數的都懂。。。

2.3.2對頂點進行投影

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

參考以上圖檔。給出一個點(x,y,z)求它在投影平面z=d上的投影點(x`,y`,d)。通過相似三角形很容易得到

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

2.3.3規範化裝置坐标(NDC)

    上一節中我們有提到一個關鍵參數橫縱比r。但是不同的硬體縱橫比是不同的,我們必須為硬體指定縱橫比,否則無法執行運算。如果消除對橫縱比的依賴,會使相關的運算變得簡單。為了解決這個問題,可以将x坐标從[-r,r]區間縮放到[-1,1]區間:

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

    在映射之後,x、y坐标被稱為規範化裝置坐标(normalized device coordinates,簡稱NDC)(z坐标還沒有被規範化)。

    那就可以修改之前的投影公式,直接使用NDC空間中的x,y投影坐标:

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

    其實說了很多廢話,簡單的總結一下:NDC空間中,投影視窗高度和寬度都為2。

2.3.4用矩陣來描述投影方程

    為了保持一緻,我們将用一個矩陣來描述投影變換。不過,上述方程是非線性的(透視除法,即x',y'的分母z),無法用矩陣描述。但可以使用一種技巧将它分為兩部分實作:一個線性部分和一個非線性部分。非線性部分要除以z(透視除法)。後面會講到這個問題,現在隻需要知道,我們會因除法操作失去原始的z坐标,是以必須在變換之前儲存輸入的z坐标。可以利用齊次坐标解決這一問題,将輸入的z坐标指派給輸出的w坐标。在矩陣乘法中,将元素[2][3]設為1、[3][3]設為0(從0開始的索引)。

矩陣大緻如下:

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

    矩陣中的常量A好B在下一節讨論;這項常量用于把輸入的z坐标變換到規範化區間。将一個任意點(x,y,z,1)與該矩陣相乘,可以得到:

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

    在與投影矩陣(線性部分)相乘之後,我們要将每個坐标除以z(透視除法;非線性部分),得到最終結果:

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

2.3.5規範化深度值

    在數學概念上,當3D物體投影到平面上,就會丢失z軸的資訊(z為常數)。但事實上,我們仍然需要為深度緩存算法提供3D物體的z坐标資訊。在實際中,我們會建立一個保序函數把深度坐标(區間為[n,f])映射到一個規範化區間[0,1]。由于該函數是保序的,是以深度值的相對大小可以完整的保留下來。

    由上一節我們知道g(z)=A+B/z。若g(z)的區間為[0,1]。顯然

    在近平面上,有g(n)=A+B/n=0;

    在遠平面上,有g(f) =A+B/f =1;

    可以解得A=f/(f-n) ,B=-fn/(f-n)。

    是以,

    g(z)=f/(f-n)-nf/(f-n)z

    g(z)的曲線圖如下

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

    可以看出它是保序且非線性的。而且大部分的取值落在近平面附近。是以,大多數深度值被映射到一個很窄的取值範圍内。考慮到計算機處理小數的精度有限,是以建議讓近平面和遠平面盡可能接近,把深度的精度性問題減小的最低程度。

    此時已經可以确定出完整的透視投影矩陣:

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

    在與投影矩陣相乘之後,進行透視除法之前,幾何體所處空間稱為齊次裁剪空間(homogeneous clip space)或投影空間(projection space)。在透視除法之後,幾何體所處的空間稱為規範化裝置空間(normalized device coordinates,簡稱NDC)。

2.3.6XMMatrixPerspectiveFovLH

    透視投影矩陣P可由如下XNA函數生成:

XMMATRIX XMMatrixPerspectiveFovLH(// returns projection matrix
    FLOAT FovAngleY, // vertical field of view angle in radians
    FLOAT AspectRatio, // aspect ratio = width / height
    FLOAT NearZ, // distance to near plane
    FLOAT FarZ); // distance to far plane
           

    一下代碼片段示範XMMatrixPerspectiveFovLH函數的使用方法。這裡,我們将垂直域角設為45°,近平面設為1,遠平面設為1000(在觀察空間中)

XMMATRIX P = XMMatrixPerspectiveFovLH(0.25f*MathX::Pi,
    AspectRatio(),1.0f,1000.0f);
           

    橫縱比要比對視窗的橫縱比:

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

3.曲面細分階段

    曲面細分(Tessellation)是指通過添加三角形的方式對一個網格的三角形進行細分,這些新添加的三角形可以偏移到一個新的位置,讓網格的細節更加豐富。

    下面是曲面細分的一些優點:

    1.我們可以通過曲面細分實作細節層次(level-of-detail,LOD),使靠近相機的三角形通過細分産生更多細節,而遠離相機的三角形保持不變。通過這種方式,我們隻需要在需要細節的地方使用更多的三角形就行了。

    2.我們可以在記憶體中儲存一個低細節(三角形數量更少)的網格,但是可以實時地添加額外的三角形,這樣可以節省記憶體。

    3.我們可以在一個低細節的網格上處理動畫和實體效果,而隻是在渲染時才使用細分過的高細節網格。

4.幾何着色器階段

    幾何着色器階段(geometry shader stage)是可選的,這裡隻做一個簡短的概述。幾何着色器以完整的圖元作為輸入資料。例如,當我們繪制三角形清單時,輸入到幾何着色器的資料是構成三角形的三個點。幾何着色器的主要優勢是它可以建立或銷毀幾何體。例如,輸入圖元可以被擴充為一個或多個其他圖元,或者幾何着色器可以根據某些條件拒絕輸出某些圖元。這一點與頂點着色器有明顯的不同:頂點着色器無法建立頂點,隻要輸入一個頂點,那就必須輸出一個頂點。幾何着色器通常用于将一個點擴充為一個四邊形,或者将一條線擴充為一個四邊形。

5.裁剪階段

    我們必須完全丢棄在平截頭體之外的幾何體,裁剪與平截頭體邊界相交的幾何體,隻留下平截頭體内的部分;

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

6.光栅化階段

    光栅化(rasterization)階段的主要任務是為投影後的3D三角形計算像素顔色。

6.1視口變換

    在裁剪之後,硬體會自動執行透視除法,将頂點從齊次裁剪空間變換到規範化裝置空間(NDC)。頂點進入NDC空間後,構成2D圖像的2D x、y坐标就會被變換到背景緩沖區中的一個稱謂視口(viewport)的矩形區域内。在該變換之後,x、y坐标講義像素為機關。通常,視口變換不修改z坐标,因為z坐标還要由深度緩存使用,但是我們可以通過D3D11_VIEWPORT結構體的MinDepth和MaxDepth值修改z坐标的取值範圍。MinDepth和MaxDepth取值必須在0和1之間。

6.2背面消隐

    一個三角形有兩個面。用“左手定則”來區分正反。

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

    3D空間中的大部分物體都是封閉實心物體。錄影機不會看到實心物體朝後的三角形,是以繪制他們是毫無意義的,這就是背面消隐的原理。這可以将所要處理的三角形數量降低到原數量的一半。

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段
Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

6.3頂點屬性插值

    之前提到過,頂點除了位置資訊,還可以包含其他屬性,比如顔色、法線向量和紋理坐标。在視口變換之後,這些屬性必須為三角形表面上的每個像素進行插值。頂點深度值也必須進行插值,以使每個像素都有一個可應用于深度緩存算法的深度值。對螢幕空間中的頂點屬性進行插值,其實就是對3D空間中的三角形表面進行線性插值;這一工作需要借助所謂的透視校正插值(perspective correct interpolation)來實作。本質上,三角形表面内部的像素顔色都是通過頂點插值得到的。

Directx11渲染管線概述1.輸入裝配階段2.頂點着色器階段3.曲面細分階段4.幾何着色器階段5.裁剪階段6.光栅化階段7.像素着色器階段8.輸出合并階段

    我們不必關心透視精确插值的數學細節,因為硬體會自動完成這一工作。有興趣的話,自行查閱。

7.像素着色器階段

    像素着色器是由我們編寫的在GPU上執行的程式。像素着色器會處理每個像素片段,它的輸入是插值後的頂點屬性,由此計算出一個顔色。像素着色器可以非常簡單的輸出一個顔色,也可以很複雜,例如實作逐像素光照、反射和陰影等效果。

8.輸出合并階段

    當像素片段由像素着色器生成之後,它們會被傳送到渲染管線的輸出合并(output merger,簡稱OM)階段。在該階段中,某些像素片段會被丢棄。未丢棄的像素片段會被寫入背景緩沖區。混合(blending)工作是在該階段中完成的,一個像素可以與背景緩沖區中的目前像素進行混合,并以混合後的值作為該像素的最終顔色。某些特殊效果,比如透明度,就是通過混合來實作的