02 - Metal學(xué)習(xí)之渲染管線

通過這篇文章你將了解Metal渲染管線的工作流程,這有助于你深入了解Metal工作流程,以及Metal是基于什么現(xiàn)有條件設(shè)計(jì)的。
參考文章: 《Metal by Tutorials》

1.CPU和GPU

所有計(jì)算機(jī)都有一個(gè)中央處理單元(CPU),可以驅(qū)動計(jì)算機(jī)上的操作和管理資源。他們還有一個(gè)圖形處理單元(GPU)。

GPU是一種專門的硬件組件,可以非常快速地處理圖像、視頻和大量數(shù)據(jù)。這被稱為吞吐量。吞吐量由特定時(shí)間單位處理的數(shù)據(jù)量來衡量。

另一方面,CPU無法非??焖俚靥幚泶罅繑?shù)據(jù),但它可以非??焖俚靥幚碓S多順序任務(wù)(一個(gè)接一個(gè))。處理任務(wù)所需的時(shí)間稱為延遲。

理想的設(shè)置包括低延遲和高吞吐量。低延遲允許串行執(zhí)行排隊(duì)任務(wù),因此CPU可以執(zhí)行命令,而不會系統(tǒng)變得緩慢或無響應(yīng);高吞吐量允許GPU異步渲染視頻和游戲,而不會使CPU停滯不前。由于GPU具有高度并行化的架構(gòu),專門重復(fù)執(zhí)行相同的任務(wù),并且很少或沒有數(shù)據(jù)傳輸,因此它能夠處理大量數(shù)據(jù)。

2. 渲染管線

如下圖所示,渲染管線分為以下幾個(gè)部分:


截屏2022-06-01 16.42.11.png

圖形管道將頂點(diǎn)帶過多個(gè)階段,在此期間,頂點(diǎn)的坐標(biāo)在不同空間之間轉(zhuǎn)換。
作為程序員,您只關(guān)心頂點(diǎn)和片段處理階段,因?yàn)橹挥兴鼈兪强删幊屉A段。

1.頂點(diǎn)獲取:

通過設(shè)置頂點(diǎn)緩沖對象,可以給GPU傳遞頂點(diǎn)數(shù)據(jù)。
類似如下代碼:

renderEncoder.setVertexBuffer(vertexBuffer, offset: 0, index: 0)

2.頂點(diǎn)處理

在這個(gè)階段,頂點(diǎn)是單獨(dú)處理的。您編寫代碼來計(jì)算每個(gè)頂點(diǎn)照明和顏色。更重要的是,您通過各種坐標(biāo)空間發(fā)送頂點(diǎn)坐標(biāo),以獲取它們在最終幀緩沖區(qū)中的位置。

3.圖元裝配

上一階段將分組為數(shù)據(jù)塊的處理頂點(diǎn)發(fā)送到此階段。需要記住的是,屬于相同幾何形狀(原始)的頂點(diǎn)始終位于同一塊中。這意味著一個(gè)點(diǎn)的一個(gè)頂點(diǎn),或一條線的兩個(gè)頂點(diǎn),或一個(gè)三角形的三個(gè)頂點(diǎn),將始終在同一塊中,因此永遠(yuǎn)不需要第二個(gè)塊獲取。

不僅僅是頂點(diǎn)信息,CPU同時(shí)還會發(fā)送與頂點(diǎn)相關(guān)聯(lián)的信息。類似下面的代碼:

renderEncoder.drawIndexedPrimitives(type: .triangle, 
indexCount: submesh.indexCount, indexType: submesh.indexType, indexBuffer: submesh.indexBuffer.buffer, 
indexBufferOffset: submesh.indexBuffer.offset)

第一個(gè)參數(shù)是繪制圖元的類型,這里Metal支持五種圖元類型(和OpenGL ES類似)
如下圖所示:


截屏2022-06-01 17.23.42.png

圖示清晰地展示了幾種類型的區(qū)別,這里就不做過多贅述了。

4.光柵化

目前有兩種現(xiàn)代渲染技術(shù)在不同的路徑上發(fā)展,但有時(shí)一起使用:光線追蹤和光柵化。他們完全不同;兩者都有利弊。

在渲染靜態(tài)和遙遠(yuǎn)的內(nèi)容時(shí),首選光線追蹤——您將在第18章“用光線渲染”中閱讀更多內(nèi)容,而當(dāng)內(nèi)容更接近相機(jī)且更動態(tài)時(shí),更傾向于光柵化。

通過光線追蹤,對于屏幕上的每個(gè)像素,它都會向場景發(fā)送光線,看看是否與物體相交。如果是,請將像素顏色更改為該對象的顏色,但前提是該對象比之前為當(dāng)前像素保存的對象更接近屏幕。

光柵化的作用相反:對于場景中的每個(gè)對象,將光線發(fā)送回屏幕,并檢查對象覆蓋的像素。深度信息與光線追蹤的方式相同,因此如果當(dāng)前對象比之前保存的對象更近,它將更新像素顏色。

此時(shí),從上一階段發(fā)送的所有連接頂點(diǎn)都需要使用其X和Y坐標(biāo)在二維網(wǎng)格上表示。此步驟稱為三角形設(shè)置。

在這里,光柵化器需要計(jì)算任何兩個(gè)頂點(diǎn)之間線段的斜率或陡度。當(dāng)知道三個(gè)頂點(diǎn)的三個(gè)斜率時(shí),三角形可以從這三個(gè)邊形成。

接下來,一個(gè)名為掃描轉(zhuǎn)換的過程在屏幕的每一行上運(yùn)行,以查找十字路口,并確定什么是可見的,什么是不可見的。此時(shí),要在屏幕上繪圖,只需要它們確定的頂點(diǎn)和斜率。

掃描算法確定線段上的所有點(diǎn)或三角形內(nèi)的所有點(diǎn)是否可見,在這種情況下,三角形完全充滿顏色。
簡而言之,光柵化就是把矢量圖形轉(zhuǎn)化為像素點(diǎn)的過程。

5.頂點(diǎn)處理

截屏2022-06-01 18.03.21.png

如上圖所示:
頂點(diǎn)獲取單元從內(nèi)存中抓取頂點(diǎn),并將其傳遞給調(diào)度器單元。

調(diào)度器單元知道哪些著色器內(nèi)核可用,因此它調(diào)度工作。

工作完成后,分銷商部門知道這項(xiàng)工作是頂點(diǎn)還是碎片處理。

如果是頂點(diǎn)處理工作,它會將結(jié)果發(fā)送到原始匯編單元。此路徑繼續(xù)到光柵化單元,然后返回到調(diào)度器單元。

如果是片段處理工作,它會將結(jié)果發(fā)送到顏色書寫單元。

最后,彩色像素被送回內(nèi)存。

6.幀緩沖

一旦碎片被處理成像素,分銷商單元就會將其發(fā)送到顏色書寫單元。該單元負(fù)責(zé)在稱為幀緩沖區(qū)的特殊內(nèi)存位置寫入最終顏色。從這里,視圖的每個(gè)幀都會刷新其彩色像素。但這是否意味著顏色在屏幕上顯示時(shí)寫入幀緩沖區(qū)?

使用一種稱為雙緩沖的技術(shù)來解決這種情況。當(dāng)?shù)谝粋€(gè)緩沖區(qū)顯示在屏幕上時(shí),第二個(gè)緩沖區(qū)在后臺更新。然后,交換兩個(gè)緩沖區(qū),第二個(gè)緩沖區(qū)顯示在屏幕上,而第一個(gè)緩沖區(qū)更新,循環(huán)繼續(xù)。
大致了解完渲染管線后,接下來就是結(jié)合demo來了解Metal編程了。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容