渲染流程的3個階段:應(yīng)用階段粱挡,幾何階段询筏,光柵化階段
應(yīng)用階段:由開發(fā)者主導(dǎo)嫌套,CPU負(fù)責(zé)實(shí)現(xiàn)踱讨。
3個任務(wù):a.準(zhǔn)備場景數(shù)據(jù)(模型痹筛,光源帚稠,攝像機(jī)等) b.剔除(提高渲染性能) c.設(shè)置渲染狀態(tài)(材質(zhì)滋早,紋理杆麸,shader)昔头。這一階段最重要是輸出渲染所需的幾何信息减细,就是渲染圖元(包括點(diǎn)線面等)
幾何階段:在GPU上處理幾何相關(guān)事情未蝌,進(jìn)行逐個頂點(diǎn),多邊形操作(如繪制的圖元是什么左冬,怎么繪制拇砰,在哪繪制)
重要任務(wù):把頂點(diǎn)坐標(biāo)變化到屏幕空間里除破,輸出屏幕空間二維頂點(diǎn)坐標(biāo)瑰枫,每個頂點(diǎn)對應(yīng)的深度值光坝,著色相關(guān)信息盯另。
光柵化階段:GPU運(yùn)行鸳惯。使用幾何階段數(shù)據(jù)悲敷,產(chǎn)生屏幕像素后德,渲染最終圖像瓢湃。
2個主要任務(wù):a.計算每個圖元覆蓋了哪些像素 b.為這些像素計算它們的顏色。
CPU和GPU通信3個階段:數(shù)據(jù)加載到顯存雾叭,設(shè)置渲染狀態(tài)织狐,調(diào)用DrawCall
數(shù)據(jù)加載至顯存中:渲染數(shù)據(jù)從硬盤加載到內(nèi)存移迫,再加載至顯存厨埋。顯卡對RAW沒有直接訪問權(quán)限捐顷,顯卡對顯存訪問更快迅涮。
設(shè)置渲染狀態(tài):定義場景中網(wǎng)格怎么被渲染(如使用哪個shader蛹头,light,material)
調(diào)用Draw Call :CPU調(diào)用圖像編程接口托享,命令GPU進(jìn)行渲染操作闰围。
GPU流水線(幾何階段+光柵化階段)
頂點(diǎn)著色器 Vertex Shader? :頂點(diǎn)著色器是完全可編程的,通常用于實(shí)現(xiàn)頂點(diǎn)的空間變換校仑、頂點(diǎn)著色等功能迄沫。
GPU第一階段羊瘩,輸入來源于CPU尘吗。處理單位是頂點(diǎn)摇予。本身不可創(chuàng)建和銷毀頂點(diǎn)侧戴。獨(dú)立性酗宋,處理速度快蜕猫。
主要任務(wù):1回右,坐標(biāo)變化 2翔烁,計算頂點(diǎn)顏色蹬屹。
曲面細(xì)分著色器 Tessellation Shader :曲面細(xì)分著色器是一個可選的著色器慨默,用于細(xì)分圖元厦取。
幾何著色器 Geometry Shader :幾何著色器是一個可選的著色器蒜胖,用于執(zhí)行逐圖元著色操作,或產(chǎn)生更多圖元岁经。
裁剪 Clipping : 圖元和攝像機(jī)的視野3種關(guān)系。是將那些不在攝像機(jī)視野內(nèi)的頂點(diǎn)剪裁掉塘慕,并剔除某些三角圖元的面片图呢。
屏幕映射 Screen Mapping :屏幕映射是不可配置和編程的蛤织,負(fù)責(zé)把每個圖元的坐標(biāo)轉(zhuǎn)換到屏幕坐標(biāo)系。實(shí)際就是一個縮放過程涨椒。
三角形設(shè)置 :計算光柵化一個三角網(wǎng)格所需的信息免猾,它的輸出是為下一步驟做準(zhǔn)備掸刊。
三角形遍歷:找到哪些像素被三角網(wǎng)格覆蓋的過程。對應(yīng)像素會生成一個片元,而片元中的狀態(tài)是對三個頂點(diǎn)的信息進(jìn)行插值得到的躺屁。
片元著色器 Fragment Shader(DX:Pixel Shader)?:輸入是上一步對頂點(diǎn)信息插值得到的結(jié)果犀暑,輸出是顏色值(著色)
補(bǔ)充:片元著色器這一步驟可以完成很多重要的渲染技術(shù)徊都,比如 紋理采樣:在頂點(diǎn)著色器階段輸出每個頂點(diǎn)對應(yīng)的UV坐標(biāo)(也叫紋理坐標(biāo))暇矫,然后經(jīng)過光柵化階段對三角網(wǎng)格的3個頂點(diǎn)對應(yīng)的UV坐標(biāo)進(jìn)行插值后,就可以得到覆蓋的片元的UV坐標(biāo)了房轿。
可以這樣理解貼圖:不妨把紋理圖片想象成一片彈性很好的橡皮薄膜所森,貼圖就相當(dāng)于用釘子把橡皮薄膜固定在與其紋理坐標(biāo)相對應(yīng)的頂點(diǎn)上。
逐片元操作:OpenGL中的說法,在DX中凭需,叫輸出合并階段粒蜈。
該階段的任務(wù):
決定每個片元的可見性枯怖。涉及了很多測試工作度硝,例如模板(Stencil)測試(小于或者大于等于模板緩沖區(qū)中該片元的模板值就舍棄該片元蕊程,通常用于限制渲染區(qū)域。)驼唱、深度(Depth)測試(大于等于深度緩沖區(qū)中該片元的深度值就舍棄該片元)等藻茂;
如果一個片元通過了所有測試,就需要把這個片元的顏色值和已經(jīng)存儲在顏色緩沖區(qū)中的顏色進(jìn)行混合,最后再寫入顏色緩沖區(qū)中辨赐。也就是將片元的顏色值一個個地堆疊起來优俘。
總結(jié):只需要在一個Unity Shader中設(shè)置一些輸入、編寫頂點(diǎn)著色器和片元著色器掀序、設(shè)置一些狀態(tài)就可以達(dá)到大部分常見的屏幕效果。
CPU森枪、OpenGL/DirectX视搏、顯卡驅(qū)動和GPU之間的關(guān)系圖:
OpenGL/DirectX是圖像應(yīng)用編程接口,架起了應(yīng)用程序和GPU溝通的橋梁县袱。應(yīng)用程序向這些接口發(fā)送渲染指令浑娜,而這些接口會依次向顯卡驅(qū)動發(fā)送渲染命令。顯卡驅(qū)動就是顯卡的操作系統(tǒng)式散,它知道如何和顯卡中的GPU打交道筋遭,并將渲染命令翻譯成GPU能理解的機(jī)器語言。
優(yōu)化:批處理可以有效減少Draw Call暴拄。Draw Call造成性能問題的元兇是CPU 漓滔。很簡單的一個道理:10000個1kb的小文件和1個10M的大文件同時傳輸,肯定是1個10M的文件傳得快許多乖篷。
為避免我們看到正在光柵化的圖元响驴,GPU采取雙重緩沖的機(jī)制,渲染發(fā)生在后置緩沖中撕蔼,渲染結(jié)束后豁鲤,GPU就會交換后置緩沖區(qū)和前置緩沖區(qū)中的內(nèi)容。
最后附上萬大的神圖: