渲染流水線
僅為本菜雞自己學(xué)習(xí)記錄分享,如有錯誤還請各位大佬指出。

渲染管線整體流程分為主要四個階段:
應(yīng)用階段
幾何階段
光柵化階段
逐片元操作(在一些資料中這個階段也并入光柵化階段)
1.應(yīng)用階段
是一般圖形渲染管線概念上的第一個階段,通過軟件方式在CPU上實現(xiàn),開發(fā)者能夠?qū)υ撾A段進(jìn)行完全控制。在這一階段中所有數(shù)據(jù)需要從硬盤(HDD)加載到系統(tǒng)內(nèi)存(RAM)中。然后將數(shù)據(jù)加載到顯卡的儲存空間顯存中(VRAM)。

其中又可細(xì)分為下圖中幾個階段
(1)準(zhǔn)備基本場景數(shù)據(jù)
物體數(shù)據(jù):變換數(shù)據(jù)(位置,旋轉(zhuǎn),縮放等)網(wǎng)格數(shù)據(jù)(頂點(diǎn)位置,UV貼圖等)
光源信息:光源類型(方向光,點(diǎn)光,聚光等),顏色,位置方向角度等
攝像機(jī)參數(shù):位置,方向,近遠(yuǎn)裁剪平面,正交透視,視口比例尺寸等
陰影信息:是否開啟,判斷光源范圍內(nèi)是否有可投射陰影物體,陰影強(qiáng)度等參數(shù)
(2)加速算法,粗粒度剔除等
碰撞檢測,加速算法,輸入檢測,動畫,力反饋,紋理動畫,變換仿真,幾何變形
(3)設(shè)置渲染狀態(tài),準(zhǔn)備渲染參數(shù)
渲染設(shè)置:合批方式,光源屬性材質(zhì),使用哪個頂點(diǎn)/片元著色器等
繪制物體的順序:材質(zhì)RenderQueue,UICanvas,相對攝像機(jī)距離等等
渲染目標(biāo):FrameBuffer,RenderTexture
渲染模式:前向渲染,延遲渲染
(4)輸出到顯存
頂點(diǎn)數(shù)據(jù):位置顏色法線紋理uv等
其他收據(jù):MVP變換,紋理貼圖,其他數(shù)據(jù)
在這些都完成之后 CPU就會調(diào)用一個渲染命令DrawCall來調(diào)用GPU

GPU和CPU之間有一個命令緩沖區(qū),可以實現(xiàn)相互獨(dú)立工作
提交大量很小的DrawCall會造成CPU性能瓶頸
可以使用批處理合并過程一個大的DrawCall
2.幾何階段
幾何階段主要負(fù)責(zé)大部分多邊形操作和頂點(diǎn)操作

其中頂點(diǎn)著色前模型視圖變換后 中間可選曲面細(xì)分著色器,幾何著色器等頂點(diǎn)處理
(1)模型和視圖變換 Model and View Transform
為了方便投影和裁剪,需要對相機(jī)和所有模型進(jìn)行視點(diǎn)變換,模型變換是為了讓模型變換到合適的渲染空間中,視圖變換為了讓相機(jī)位于原點(diǎn),同時朝向z軸負(fù)方向。這個空間通常稱為觀察空間或相機(jī)空間。

(1.5)曲面細(xì)分著色器,幾何著色器
在曲面細(xì)分中可以使用合適的細(xì)分算法,生成高精度網(wǎng)格提升細(xì)節(jié)
在幾何中可以添加額外vertex 轉(zhuǎn)換為新的圖元
a.曲面細(xì)分著色器 Tessellation Shader
主要由三部分構(gòu)成,其中Hull Shader和Domain Shader是可編程的
他的輸入是多個頂點(diǎn)的集合,包含每個頂點(diǎn)屬性,可以指定一個Patch包含的頂點(diǎn)數(shù)以及自己的屬性。
作用就是將圖元細(xì)分(可以是三角形 矩形等) 輸出細(xì)分后的頂點(diǎn)

<1>Hull Shader
主要作用是來定義一些細(xì)分的參數(shù),比如每一條線上邊上如何細(xì)分
參數(shù)解析:
·Tesselation Factor:決定一個邊分為幾部分

equal_Spacing:幾就幾等分

fractional_even_spacing:最小值2向上取最小偶數(shù),把周長分為n-2的等長部分以及兩端不等長部分

fractional_odd_spacing:最小值1 向上取最近的奇數(shù),把周長分為n-2個不等長部分以及兩端不等長部分
·Inner Tessellation Factor:決定內(nèi)部如何畫,通過延長線做交點(diǎn)直到不能做為止

<2>Tessellation Primitive Generator
進(jìn)行細(xì)分操作
<3>Domain Shader
細(xì)分后的空間是重心空間,Domain Shader要把他轉(zhuǎn)換到我們要用的空間
b. 幾何著色器 Geometry Shader
輸入為圖元(三角形,矩形,線等)根據(jù)圖元的不同,shader中會出現(xiàn)對應(yīng)不同數(shù)量的頂點(diǎn)
輸出同樣為圖元,一個或多個,需要自己從頂點(diǎn)構(gòu)建,順序很重要
同時需要定義最大輸出的頂點(diǎn)數(shù)
(2)頂點(diǎn)著色 Vertex Shading
著色計算的一部分在頂點(diǎn)著色著色器上執(zhí)行,其他計算可在光柵化期間進(jìn)行,頂點(diǎn)著色的數(shù)據(jù)計算完畢后會發(fā)送到光柵化階段進(jìn)行插值操作。
(3)投影 Projection
投影是為了將視體變換到規(guī)范立方體(CVV)中,目前主要有兩種投影方式:正交投影(orthographic projection)和透視投影(perspective projection)

(4)裁剪Clipping
主要是對于部分位于內(nèi)部的圖元進(jìn)行裁剪操作,將單位立方體之外的圖元剔除掉,保留內(nèi)部,產(chǎn)生一個新圖元

(5)屏幕映射 Screen Mapping
屏幕映射主要目標(biāo)就是找到在屏幕坐標(biāo)系上的對應(yīng)位置

3.光柵化階段
這個階段完成從二維頂點(diǎn)所處屏幕空間到屏幕上像素的轉(zhuǎn)換,光柵化中不只是會處理三角形圖元(含有Triangle只是因為大部分是三角形) 同樣也要處理點(diǎn)線等其他圖元,以方便后續(xù)的Pixel Processing

(1)三角形設(shè)置Triangle Setup
在這里會計算每條邊上的像素坐標(biāo),得到三角形邊界的表示方式,以幾何階段處理的各種著色數(shù)據(jù)的插值操作
(2)三角形遍歷
會逐像素進(jìn)行檢查 判斷該像素中心是否由三角形覆蓋。每個三角形片段的屬性由三個三角形頂點(diǎn)數(shù)據(jù)插值形成。
通過向量叉乘可以快速判斷是否在三角形內(nèi),
處理邊界上的點(diǎn)不同的API規(guī)定不同。

目前比較傳統(tǒng)的劃分方式為Standard Rasterization除此外DX11還引入了兩種新遍歷類型Conservative Rasterization CR。

在此圖中常規(guī)方法是取黃色+綠色 在outer-CR在取綠+黃+藍(lán) 在inner-CR只取綠
對于插值方法常用的有三種:
最近鄰Nearest Neighbor,距離Distance和重心坐標(biāo)coordinate system
下面淺談一下重心坐標(biāo)的解決方法:

三角形平面內(nèi)任意一點(diǎn)都可以用三個點(diǎn)的坐標(biāo)線性表示出來
如果都非負(fù)那么就在三角形內(nèi)

重心坐標(biāo)計算可以用面積來計算
但有更加方便的方法 叉乘計算

之后就可以對頂點(diǎn)的各個屬性 如顏色,法線等進(jìn)行插值
4.逐片元操作
逐片元階段主要是為給各個像素填上正確顏色與正確的可見性,得到相應(yīng)圖像信息
(1)像素著色階段
通過插值得到的著色數(shù)據(jù)計算出一種或多種顏色信息傳入下一階段。在這一階段中有大量的技術(shù)可使用(如紋理貼圖等)。
但他局限在于僅可影響單個片元,不可以將自己的任何結(jié)果發(fā)給鄰居(但個人認(rèn)為實際操作可以rendertex進(jìn)行這樣操作,有點(diǎn)費(fèi)就是了)

(2)融合Merging
通常運(yùn)行階段的GPU子單元并非完全可編程,但可高度配置,支持多種效果。
在此階段不僅要通過模板測試 深度測試等進(jìn)行可見性測試,還要將當(dāng)前儲存于緩沖中的顏色與當(dāng)前顏色進(jìn)行合并。
其中模板測試和深度測試分別主要通過模板緩沖器和Z緩沖區(qū)實現(xiàn)

除此之外還有累計緩沖區(qū),alpha通道等來過濾和捕獲片段信息。
5.其他操作

在渲染流程完成之后,再對最后輸出的結(jié)果進(jìn)行處理,簡稱后處理
參考:
1.渲染流水線 - 知乎 (zhihu.com)
Unity Shader入門精要