Shader - Unity中的渲染管道

着色器用於定義對象的外觀(材質屬性)以及它對光的反應,因爲必須在着色器中構建光照計算,然而可能會存在很多類型的光影,所以編寫Shader是非常麻煩的一件事。Unity爲了簡化編寫Shader的操作,提供了Surface Shaders,它會將所有的光照,陰影,光照貼圖,向前渲染和延遲渲染都會自動處理。

如何選擇渲染通道(Pass)以及燈光如何應用,都取決於採用什麼樣的渲染路徑。Shaer中的每個Pass適用於什麼樣的渲染路徑都是通過PassTags中的LightMode 來定義的。
Unity中包含的渲染路徑有:

渲染路徑 支持的LightMode
Forwawrd Rendering(正向渲染) ForwardBase和ForwardAdd Pass會被使用
Deferred Shading(延遲着色) Deferred Pass會被使用
legacy Deferred Lighting(遺留 延遲光照) PrepassBase和PrepassFinal Pass會被使用
legacy Vertex Lit(遺留 頂點光照) Vertex,VertexLMRGBM和VertexLM Pass 會被使用
上述任何一個渲染路徑,爲了渲染陰影或深度紋理,ShadowCaster Pass會被使用

Forward Rendering path(正向渲染路徑)
在Forward Rendering 路徑中,在影響對象的所有燈光中,一些最亮的燈會以逐像素的方式進行照明,然後會有4個燈光以逐頂點的方式進行照明,剩餘的燈光會以SH(球面諧波)的方式進行渲染。主要規則如下:

1.將渲染模式設置爲"Not Important"的燈始終是按頂點或者SH進行渲染
2.最亮的平行光會以逐像素的方式進行渲染。
3.將渲染模式設置爲“Important”的燈始終爲逐像素進行渲染。
4.最多會有4個光源按照逐頂點的方式進行渲染
5.經過以上操作後,如果逐像素渲染的燈光個數小於Quality Setting設置中Pixel Light Count的數量話,會按照亮度從高到低的順序,選擇合適的燈光數量,進行逐像素渲染。

渲染流程如下:

1.Forward Base Pass 會執行最亮的逐像素平行光和所有的逐頂點/SH燈光渲染。
2.Forward Add Pass 會在每個逐像素燈光(除逐像素平行光以外的)進行一次渲染。 

例如:
在這裏插入圖片描述
上圖中,對象(圓圈)受到燈光A到H的影響,假設A到H都具有相同的顏色和強度,且所有燈光都具有自動渲染模式,所以他們將按照與對象距離來進行排序,前面的燈光會以逐像素的方式進行渲染(A-D,具體數量會根據質量設置中的數據來設置),然後就是以逐頂點的燈光渲染(D-G,最到4個燈光),剩餘的燈光會以SH(G-H)的方式進行渲染。如圖:
在這裏插入圖片描述

注意,在不同的模式渲染中有重疊渲染的部分,這樣當物體和光線移動時,不會出現太多的"燈光跳躍"
除A燈光外,其餘逐像素渲染燈光會調用Forward Add Pass。

ForwardBase :使用一個逐像素平行光和所有SH/頂點光源渲染對象,在此過程中還會添加着色器中的光照貼圖,環境光和自發光。在此渲染過程中方向光可以具有陰影(注意光照貼圖對象不會從SH燈獲取照明)。
如果在Pass中使用了“OnlyDirectional”標籤,ForwardBase 通道僅渲染主方向光,環境/光探測器和光照貼圖(SH和頂點光不包括在Pass數據中)。
ForwardAdd :會爲所有影響該對象的逐像素光源渲染一次(除主平行光外) 。默認情況下,這些過程中的燈光是沒有陰影的,除非使用了multi_compile_fwdadd_fullshadows這樣的編譯指令,來生成多個着色器程序變體。
如果着色器沒有提供適當的Pass(即沒有ForwardBase也不存在ForwardAdd),則該對象的渲染方式語Vertex Lit 路徑中的渲染方式相同。

SH(球面諧波)的渲染速度是非常塊的,並且在CPU上的成本很低,實際上可以自由地應用GPU(ForwardBase通道總是計算SH照明,由於SH的工作方式,所以無論多少SH燈,成本都是一樣的)。
SH的缺點有:

1.它們是在頂點的基礎上進行計算,所以不支持Cookie和法線貼圖
2.SH照明頻率很低,無法有明顯的照明過度。也隻影響漫反射光照(鏡面高管的頻率太低)。
3.SH照明不是局部的,靠近某些表面的球諧函數點光源或聚光燈會看起來有些彆扭。

Deferred shading Rendering path(延遲着色渲染路徑)
使用Deferred shading 時,對可影響GameObject的燈光數量沒有限制,所有燈光都會按逐像素的方式評估光照,所以它們可以與法線題圖等正確交換,所有的燈光都可以有Cookie和陰影。
Deferred shading 的優點:

照明的處理開銷與光照的像素數量成正比,這是由場景中光的大小決定,而不是它照亮了多少遊戲物體,因此可以通過保持較小的光線來提高性能。
延遲着色也具有高度一致和可預測的行爲,每個光的效果都是按像素計算的,因此沒有在大三角形上分解的光照計算。

Deferred shading 的缺點:

延遲照明沒有真正的抗鋸齒支持,也無法處理半透明的GameObject(這些是使用Forward Rendering渲染的)。
Mesh Render(網格渲染器)和Receive Shadows(接收陰影)標誌也不支持。
剔除遮蔽圖的支持方式有限(最多可以使用四個剔除遮蔽圖,即:剔除層遮蔽圖必須至少包含減去 4 個任意層後的所有層,所以 32 層中必須設置 28 層。否則會得到圖形假象。)。

使用要求:

1.需要具有多個渲染目標(MRT)的顯卡,Shader Model 3.0(或以上)的圖形卡,並支持深度渲染紋理。2006年後大多數pc顯卡都支持延遲着色,從GeForce 8xxx,Radeon x2400,Intel G45開始。
2.移動設備上不支持,主要由於使用MRT格式(某些GPU支持多個渲染目標,但只支持非常有限的位數)。
3.使用正交投影時,不支持延遲渲染。如果相機的投影模式設置爲'Orthographic(正交)',則相機會退回到“Forward Rdndering”。

性能:
延遲着色中的實時光的渲染開銷與光照像素的數量成正比,與場景複雜度無關,所以小的點光等和聚光燈在性能上更有優勢。如果它們被場景遊戲對象完全或部分遮擋,可能會獲得更好的效果。
有陰影的燈光比沒有的陰影的燈要耗費的性能更多,在延遲渲染中,陰影投射的遊戲對象仍然需要爲每個陰影投射光渲染一次或多次。此外,應用陰影的光照着色器比禁用陰影時使用的渲染開銷更高。

細節:

使用延遲渲染着色時,Unity中的渲染過程分爲兩步:
G-buffer Pass:遊戲對象被渲染成具有漫反射色、高光色、平滑度、世界空間法線、發射和深度的屏幕空間緩衝器。
Lighting Pass:先前生成的緩衝區用於將照明添加到發射緩衝區。

不能處理延遲渲染的着色(物體),在該過程完成後會使用Forward Rendering 路徑進行渲染。

默認g-buff佈局:
RT0,ARGB32格式:漫反射顏色(RGB),遮擋(A)。
RT1,ARGB32格式:鏡面反射顏色(RGB),粗糙度(A)。
RT2,ARGB2101010格式:世界空間標準(RGB),未使用(A)。
RT3,ARGB2101010(非HDR)或ARGBHalf(HDR)格式:Emission+lighting+lightmaps+reflectin 偵探 緩衝。
深度+模板緩衝區。

默認的g緩衝區佈局時160位/像素(非HDR)或192位/像素(HDR)。
相機不使用HDR時,Emission+lighting緩衝區(RT3)以對數方式編碼,以提供比ARGB32紋理通常可能的更大的動態範圍。
注意,相機使用HDR渲染時,沒有爲Emission +光照緩衝區(RT3)創建單獨的渲染目標; 相反,Camera渲染的渲染目標(即傳遞給圖像效果的渲染目標)用作RT3。

G-Buffer Pass:
渲染每個Gameobject一次,漫反射和鏡面反射顏色,表面平滑度,世界空間法線和發射+環境+反射+光照貼圖渲染爲g緩衝區紋理。g-buffer紋理被設置爲全局着色器屬性,以供稍後訪問着色器

Lighting Pass:
照明通過基於g緩衝區和深度計算照明。照明是在屏幕空間中計算的,因此處理時間與場景複雜度無關。燈光會被添加到emission 緩衝區中。
不穿過相機近平面的點光源和聚光燈會渲染爲3D形狀,並啓用Z緩衝區對場景的測試,這使得部分或完全遮擋得點光燈和聚光燈非常塊快得渲染。穿過近平面得定向燈和點/聚光燈呈現爲全屏四邊形。
如果燈光開啓了陰影,那麼它們也會在此過程中渲染並應用,陰影並不是“免費”出現的。需要渲染陰影投射器並運用更加複雜的光線着色器。
唯一可用的照明模型是 Standard,如果需要不同的模型,可以修改光照通道着色器,將內置着色器中的Internal-DeferredShading.sharder 文件的修改版本放入Asset/Resources文件夾中,然後在Edit/Project Settings/Graphics 窗口中將“Deferred”修改爲“Custom Shader”,然後更改這個在使用的着色器選項。

Legacy Deferred Lighting Rendering Paht(舊版延遲光照渲染路徑):
與Deferred shadering 相似,從Unity5.0 版本以後被認爲是傳統功能,因爲他不支持某些渲染功能(如標準着色器,反射探測器等)。

使用延遲光照時,Unity中的渲染過程會分爲3步:

1.Base Pass:渲染對象以生成具有深度,法線和鏡面反射功率的屏幕空間緩衝區。
2.Light Pass:使用前面生成的緩衝區用於計算照明到另一個屏幕空空間緩衝區(唯一可用的照明模型爲Blinn-Phong)。
3.Final Pass:再次渲染對象。它們獲取計算出的光照,將其與顏色紋理相結合,並添加任何環境/發光照明。

Vertex Lit Rendering Path (頂點照明路徑)
Vertex Lit路徑通常在一次通過中渲染每個對象,並在對象頂點出計算所有光源的光照。
Vertex Lit是最快的渲染路徑,並且具有最廣泛的硬件支持(不使用與控制檯)。
由於所有的光照都是在頂點級別計算的,因此此渲染路徑不支持大多數逐像素效果:不支持陰影,法線貼圖,cookie和非常細膩的鏡面高光。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章