概念化的流水線流程圖如下:
應(yīng)用階段 Application Stage
由CPU負(fù)責(zé)執(zhí)行击你,開(kāi)發(fā)者可完全控制偏形。
主要任務(wù)如下:
準(zhǔn)備場(chǎng)景數(shù)據(jù)
相機(jī)但指,視錐體寡痰,模型抗楔,光源等等。粗粒度剔除
剔除不可見(jiàn)物體拦坠。設(shè)置每個(gè)物體的渲染狀態(tài)
材質(zhì)连躏,貼圖,Shader等贞滨。最終輸出下一階段所需要的幾何數(shù)據(jù)入热,即渲染圖元(rendering primitives)。點(diǎn)晓铆,線勺良,三角面等。
可分為三個(gè)步驟:
將數(shù)據(jù)加載到顯存中
CPU將數(shù)據(jù)從硬盤(pán)加載到內(nèi)存中尤蒿,然后再將數(shù)據(jù)從內(nèi)存加載到顯存中郑气,之后無(wú)用的數(shù)據(jù)會(huì)從內(nèi)存中移除。
顯存速度比內(nèi)存更快腰池,而且顯卡也沒(méi)有訪問(wèn)內(nèi)存的權(quán)限尾组。設(shè)置渲染狀態(tài)
調(diào)用DrawCall
CPU向GPU發(fā)起DrawCall命令,通知其繪制哪一個(gè)物體示弓。然后GPU會(huì)直接從顯存中讀取對(duì)應(yīng)物體的數(shù)據(jù)進(jìn)行渲染操作讳侨。
幾何階段 Geometry Stage
由GPU負(fù)責(zé)執(zhí)行,用于處理所有要繪制的物體的幾何數(shù)據(jù)奏属。主要任務(wù)是將頂點(diǎn)坐標(biāo)變換到屏幕空間中跨跨,輸出屏幕空間中的二維頂點(diǎn)坐標(biāo),深度值囱皿,著色等相關(guān)信息勇婴。
光柵化階段 Rasterizer Stage
由GPU負(fù)責(zé)執(zhí)行,使用幾何階段傳遞的數(shù)據(jù)來(lái)生成屏幕上的像素嘱腥,并渲染出最終的圖像耕渴。主要任務(wù)是決定每個(gè)渲染圖元中的哪些像素應(yīng)該被繪制在屏幕上。對(duì)逐頂點(diǎn)數(shù)據(jù)(如紋理坐標(biāo)齿兔,頂點(diǎn)顏色等)進(jìn)行插值橱脸,然后進(jìn)行逐像素處理。
GPU流水線
幾何階段具體步驟:
頂點(diǎn)著色器 Vertex Shader
可編程分苇。
- 逐頂點(diǎn)坐標(biāo)變換
將坐標(biāo)從模型空間轉(zhuǎn)換到齊次裁剪空間(投影空間)添诉。然后經(jīng)過(guò)硬件透視除法后,得到歸一化設(shè)備坐標(biāo)(Normalized Device Coordinates医寿,NDC).
float4 pos = mul(UNITY_MATRIX_MVP, i.vertex);
齊次裁剪空間坐標(biāo)范圍:
X[-1,1], Y[-1,1]
Z[-1,1] OpenGL/Unity
Z[0,1] DirectX
- 逐頂點(diǎn)光照
- 準(zhǔn)備下一階段需要的數(shù)據(jù)
曲面細(xì)分著色器
可選著色器栏赴,用于細(xì)分圖元。
幾何著色器
可選著色器靖秩,用于執(zhí)行逐圖元的著色操作须眷,或用于生成更多的圖元乌叶。
裁剪 Culling
可配置。剔除不在相機(jī)視野內(nèi)的頂點(diǎn)柒爸,面片。
由于裁剪是在NDC下進(jìn)行的事扭,所以比較容易捎稚。
- 在單位立方體內(nèi)的圖元被保留
- 完全在單位立方體外的圖元被丟棄
- 部分在單位立方體內(nèi)的圖元被拆分
屏幕映射 Screen Mapping
不可控。把每個(gè)圖元的NDC坐標(biāo)轉(zhuǎn)換到屏幕坐標(biāo)系中求橄。
屏幕坐標(biāo)系是一個(gè)二維坐標(biāo)系今野,長(zhǎng)寬與顯示器分辨率對(duì)應(yīng)。
X[0, ScreenWidth]
Y[0, ScreenHeight]
Z 不變化罐农,仍為NDC坐標(biāo)中的Z值
OpenGL中屏幕坐標(biāo)原點(diǎn)為左下角条霜,DirectX中為左上角
光柵化階段步驟:
三角形設(shè)置 Triangle Setup
不可控。計(jì)算每個(gè)三角面光柵化所需的信息涵亏,比如三角形邊界像素的坐標(biāo)信息宰睡,從而得到三角形邊界的表示方式。
三角形遍歷 Triangle Traversal
不可控气筋。檢查每個(gè)像素是否被一個(gè)三角網(wǎng)格所覆蓋拆内,如果被覆蓋就會(huì)生成一個(gè)片元(fragment)。這個(gè)階段也稱(chēng)為掃描變換(Scan Conversion)宠默。
三角形遍歷會(huì)使用上一個(gè)階段的計(jì)算結(jié)果來(lái)判斷一個(gè)三角形覆蓋了哪些像素麸恍,并使用三角網(wǎng)格3個(gè)頂點(diǎn)的信息對(duì)整個(gè)覆蓋區(qū)域的像素進(jìn)行插值。比如對(duì)深度搀矫,UV抹沪,法線進(jìn)行插值。每個(gè)像素對(duì)應(yīng)的信息存儲(chǔ)在一個(gè)片元中瓤球,然后組成一個(gè)片元序列來(lái)表示當(dāng)前三角形光柵化所需要的信息融欧。
片元著色器
可編程。實(shí)現(xiàn)逐片元的著色操作冰垄。輸入為上一階段對(duì)頂點(diǎn)信息進(jìn)行插值得到的結(jié)果蹬癌,輸出為顏色值。最重要的操作為紋理采樣虹茶,得到每個(gè)像素在紋理中對(duì)應(yīng)的顏色值逝薪。
逐片元操作
可配置。主要任務(wù)有:
a. 使用模板測(cè)試蝴罪,深度測(cè)試董济,決定每個(gè)片元的可見(jiàn)性
b. 如果通過(guò)測(cè)試,則混合顏色要门,否則丟棄
-
模板測(cè)試
通常用于限制渲染的區(qū)域虏肾。例如渲染陰影廓啊,輪廓渲染等。
無(wú)論測(cè)試結(jié)果是否成功封豪,都可以對(duì)模板緩沖區(qū)進(jìn)行操作谴轮。
Ref referenceValue
ReadMask readMask
WriteMask writeMask
Comp comparisonFunction
Pass stencilOperation
Fail stencilOperation
ZFail stencilOperation
-
深度測(cè)試 DepthTest
當(dāng)模板測(cè)試成功后,才會(huì)進(jìn)入深度測(cè)試階段吹埠。
只有深度測(cè)試成功才可以寫(xiě)入深度緩沖區(qū)第步,當(dāng)然也可以設(shè)置通過(guò)了深度測(cè)試,但不寫(xiě)入深度值缘琅。
ZWrite Off/On // 是否寫(xiě)入深度值
ZTest LEqual // 深度比較操作
-
混合 Blend
當(dāng)深度測(cè)試成功后粘都,會(huì)進(jìn)入顏色混合階段。通過(guò)設(shè)置混合模式(即混合公式)將片元顏色與顏色緩沖中的顏色進(jìn)行計(jì)算刷袍,輸出新的顏色翩隧。
雙重顏色緩沖區(qū)(Dboule Buffering),在后置緩沖(Back Buffer)中渲染場(chǎng)景呻纹,等渲染完成后堆生,再與前置緩沖區(qū)(Front Buffer)交換,這樣避免了看到還沒(méi)有渲染完的場(chǎng)景雷酪。
注意:
正常情況下顽频,引擎一般會(huì)在片元著色器之前進(jìn)行模板測(cè)試與深度測(cè)試,以避免會(huì)被剔除的片元仍會(huì)參與片元著色做無(wú)用功太闺。下圖所示糯景,Unity的DepthTest在Fragment Shader之前執(zhí)行。
但是使用了AlphaTest時(shí)省骂,模板測(cè)試與深度測(cè)試無(wú)法提前執(zhí)行蟀淮,還是會(huì)延時(shí)到片元操作階段執(zhí)行。這是因?yàn)椋?/p>
- AlphaTest在Geometry隊(duì)列之后钞澳,Transparent隊(duì)列之前渲染
- AlphaTest與Geometry一樣怠惶,都是從前至后渲染
- 有一部分像素會(huì)被剔除,所以應(yīng)該可以看到這些將要被剔除像素后面的物體轧粟,但如果在剔除前就使用深度測(cè)試策治,會(huì)導(dǎo)致這些將被剔除像素后面的物體也被剔除(深度測(cè)試失敗)兰吟。片元著色器中使用Clip命令進(jìn)行剔除操作通惫。
所以可以看出,AlphaTest是比較費(fèi)性能的混蔼,多余的消耗主要在不能提前進(jìn)行模板與深度測(cè)試履腋,所以使用了AlphaTest的物體即使被遮擋了(被其它物體或被自身遮擋),還是會(huì)執(zhí)行片元著色操作。
而且遵湖,使用AlphaTest的物體在屏幕上顯示面積越大悔政,消耗越多,因?yàn)槠僮鞔螖?shù)與物體像素?cái)?shù)成正比延旧。
比如谋国,場(chǎng)景中一顆大樹(shù)的樹(shù)葉使用了AlphaTest,而且樹(shù)葉很多的話迁沫,那么所有樹(shù)葉都會(huì)執(zhí)行一次片元著色烹卒,無(wú)論它有沒(méi)有被其它樹(shù)葉遮擋住(因?yàn)榇藭r(shí)深度測(cè)試在片元著色之后才會(huì)執(zhí)行)弯洗。如果此時(shí)相機(jī)離樹(shù)很近的話,消耗就更大了逢勾。