ShaderLab
在unity中,所有的unity shader都是使用shaderlab來撰寫的,Shaderlab是unity提供的撰寫unity shader的一種說明性的語言,
Unity shader的結構
Shader名字
每一個unity shader的第一行都是通過shader語意來指定他的名字,例如:Shader "Custom/NewSurfaceShader"
材質和unity shader的橋梁:Properties
Properties陳述句塊中包含了一系列的屬性,這些屬性將出現在材質面板中,
Properties
{
_Color ("Color", Color) = (1,1,1,1)
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
}
開發者們宣告這些屬性是為了在材質面板中能夠更方便的調節各種材質的屬性,如果我們需要在shader中訪問他們,就必須使用屬性的名字,中unity中這些屬性通常由一個下劃線開始,我們需要為他指定一個型別,并且要給每個屬性一個默認值,材質面板上就會顯示這些默認值,
屬性型別有:Int,Float,Range(min,max),Color,Vector,2D,Cube,3D等,
Subshader
每一個unity shader檔案可以包含多個subshader語意塊,但至少有一個,
SubShader
{
[Tags]
[RenderSetup]
Pass
{
}
}
Subshader中定義了一系列的Pass以及可選的狀態 [RenderSetup]和標簽 [Tags] 設定,每個Pass定義了一次完整的渲染流程,如果Pass數目過多,往往會造成渲染性能的下降,
狀態
ShaderLab提供了一系列渲染狀態的設定,這些指令可以設定顯卡的各種狀態,例如是否開啟混合/深度測驗等,
| 狀態名稱 | 設定指令 | 解釋 |
| Cull | Cull Back|Front|Off | 設定剔除模式,剔除背面|正面|關閉剔除 默認 |
| ZTest | ZTest Less Greater|LEqual|GEqual|Equal|NotEqual|Always | 設定深度時使用的函式 |
| ZWrite | ZWrite On|Off | 開啟和關閉深度寫入 |
| Blend | Blend SrcFactor DstFactor | 開啟并設定混合模式 |
標簽
Tags是一個鍵值對,他的鍵和值都是字串型別的,告訴unity我們希望怎樣以及何時渲染這個物件,
| 標簽型別 | 說明 | 例子 |
| Queue | 控制渲染順序,指定該物體屬于哪一個渲染佇列 ,通過這種方式可以保證所有的透明物體可以在所有不透明物體的后邊被渲染,我們可以使用渲染佇列來控制物體的渲染順序, | Tags{"Queue" = "Transparent"} |
| RenderType | 對著色器分類,例如:這是一個不透明著色器或者設計一個透明的著色器等,這可以被用于著色器替換功能, | Tags{"RenderType" = "Opaque"} |
| DisableBatching | 一些SubShader在使用Unity批處理時會出現問題,例如使用了模型空間下的坐標進行頂點影片,這時可以通過該標簽來直接指明是否對該shader使用批處理, | Tags{"DisableBatching" = "True"} |
| ForecNoShadowCasting | 控制該SubShader的物體是否會投射陰影 | Tags{"ForceNoShadowCasting" = "True"} |
| IgnoreProjector | 設定該SubShader的物體是否受Projector影響True常用與半透明物體, | Tags{"IgnoreProjector" = "True"} |
| CanUseSpriteAtlas | 當該SubShader用于“sprite”時,將該標簽設為False | Tags{"CanUseSpriteAtlas" = "False"} |
| PriviewType | 材質面板的預型別別,一般默認材質預覽效果是球,形還可以該為"Plane" "SkyBox", | Tags{"PreviewType" = "Plane"} |
上述標簽只能在Subshader中宣告,而不可以在Pass中宣告,
Pass語意塊
通過這個名稱,我們可以使用ShaderLab的UsePass命令來直接使用其他Unity Shader中的Pass,
Psaa同樣可以設定標簽,但他的標簽不同于SubShader的標簽,這些標簽也是用于告訴渲染引擎我們希望怎樣來渲染該物體,
| 標簽型別 | 說明 | 例子 |
| LightModel | 定義該Pass在渲染管線中的角色 | Tags{"LightModel"="ForwardBase"} |
| RequireOption | 用于指定滿足某些條件是才渲染該Pass,他的值是一個由空格分割的字串, | Pass Tags{"RequireOption" = "SoftVegetation"} |
UsePass:
可以用命令來復用其他Unity Shader中的Pass;
GrabPass:
抓取螢屏并將結果儲存在一張紋理中,一用于后續的Pass處理,
Fallback
如果上邊所有的SubShader在這塊顯卡上都不能運行,那么就使用最低級別的Shader,
Unity Shader的形式
表面著色器
表面著色器是unity自己創造的一種著色器代碼型別,他需要的代碼少,unity在背后做了很多的作業,但是渲染的代價比較大,
我們可以理解成,表面著色器是Unity對頂點/片元著色器更高一層的抽象,
表面著色器被定義在SubShader中的 CGPROGRAM和ENDCG之間,因為表面著色器不需要開發者關心使用了多少個Pass每個Pass如何渲染等問題,
頂點/片元著色器
Unity中我們可以使用Cg/HLSL語言來撰寫頂點/片元著色器他們更加復雜,但是靈活性更高,
固定函式著色器
對于不支持可編程渲染管線的著色器,我們應該使用固定函式著色器來完成渲染,我們需要完全使用ShaderLab的語法,由于現在絕大多數GPU都支持可編程的渲染管線,這種固定管線的編程方式已經逐漸被拋棄,
我們如何選擇Unity Shader形式
- 除非明確要求必須使用固定函式著色器,例如要在一些很老的設備上運行,
- 如果你想和光源打交道,你可能跟喜歡使用表面著色器,但是他在移動端性能不佳,
- 如果光照比較少,那么使用頂點/片元著色器,
- 如果你有很多自定義的渲染效果,請使用頂點/片元著色器,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/397497.html
標籤:其他
上一篇:PY劃水第2天
