天天看點

Vulkan 渲染管線

大家好,接下來将為大家介紹Vulkan 渲染管線。

我們将會開啟有關圖形管線的話題,通過對圖形渲染管線的配置完成最後的三角形繪畫。所謂圖形管線就是将mesh使用到的vertices定點資料和貼圖資料,轉化為渲染targets像素的操作序列。簡要的概述如下圖所示:

Vulkan 渲染管線

Input assembler:收集最原始的頂點資料,并且還可以使用索引緩沖區複用這些資料元素,而不必複制備援的頂點資料副本。

vertex shader:會應用在每一個頂點資料,通常應用變換操作,進而将頂點的位置坐标資料從模型空間轉換為螢幕空間。在處理完畢之後會将資料繼續在管線傳遞下去。

tessellation shader:曲面着色器允許基于某些規則進一步細分幾何資料增加網格的品質。經常應用與牆面和樓梯表面,使附近看起來不是那麼平坦。

geometry shader:集合着色器應用在每一個圖元上,可用于增減圖元,它與曲面着色器類似,但更加靈活。然而,它在今天的應用中并沒有太多的應用情景,因為除了Intel的內建顯示卡外,大多數顯示卡性能支援都不理想。

光栅化階段:将圖元分解為片元。這些是填充在幀緩沖區上的像素元素。螢幕外區域的片元會被丢棄,頂點着色器輸出的資料在傳遞到片元着色器的過程中會進行内插值,如圖所示。除此之外,根據深度測試的結果也會對片元進行丢棄。

fragment shader:應用于每個片元,确定每個幀緩沖區中寫入的片中繼資料的顔色和深度值。片元着色器可以使用頂點着色器的插值資料,貼圖的UV坐标和光源法線資料。

混色操作階段:會對不同片元的顔色進行混合,最終映射到幀緩沖區的同一個像素上。片元也可以簡單的互相重寫,疊加或者根據透明度混合。

綠色的階段被稱為固定流水線。這個階段允許使用自定義的參數數值,但是它内部的工作邏輯是預制好的。

橙色的階段被稱為可程式設計階段programmable,我們可以向GPU送出自己編寫的代碼執行具體的邏輯。比如在使用fragment shader的時候,可以實作任何從貼圖到燈光的光線追蹤。這些程式同時運作在多核GPU上處理許多對象,比如并行的頂點和片段程式。

如果之前使用過舊的API(OpenGL和Direct3D),那麼将可以随意通過glBlendFunc和OMSetBlendState調用更改管線設定。Vulkan中的圖形管線幾乎不可改變,是以如果需要更改着色器,綁定到不同的幀緩沖區或者更改混合函數,則必須從頭建立管線。缺點是必須建立一些管線,這些管線代表在渲染操作中使用的不同的組合狀态。但是由于所有管線的操作都是提前知道的,是以可以通過驅動程式更好的優化它。

一些可程式設計階段是基于打算做什麼而決定的。比如,如果隻是簡單的繪制幾何圖形,則可以禁用tessellation和geometry着色器。如果隻對深度值感興趣,則可以禁用fragment着色器,這對于生成shadow map生成很有用。

在下一個章節中,我們首先建立将三角形放在螢幕上所需要的兩個可程式設計階段:vertice shader和fragment shader。固定功能的設定包括blending mode, viewport, rasterization将在之後的章節中設定。在Vulkan中設定圖形流水線的最後一部分内容涉及輸入和輸出幀緩沖區。

在initVulkan中建立函數createGraphicsPipeline并在createImageViews後立即調用。我們在下一章節介紹函數功能。

void initVulkan() {
    createInstance();
    setupDebugCallback();
    createSurface();
    pickPhysicalDevice();
    createLogicalDevice();
    createSwapChain();
    createImageViews();
    createGraphicsPipeline();
}

...

void createGraphicsPipeline() {

}
           

在結尾處分享一下Vulkan官方的圖形管線結構圖,如下:

Vulkan 渲染管線