Unity ShaderLab學習總結

本文只討論Unity ShaderLab相關的知識和使用方法。但,

既不討論渲染相關的基礎概念,基礎概念可參考Rendering Pipeline Overview等文章。
也不討論具體的渲染技巧
移動設備GPU和桌面設備GPU硬件架構上有較多不同點,詳見下面的“移動設備GPU架構簡述”一章。
一句話總結:

GameObject裏有MeshRenderer,
MeshRenderer裏有Material列表,
每個Material裏有且只有一個Shader;
Material在編輯器暴露該Shader的可調屬性。
所以關鍵是怎麼編寫Shader。

Shader基礎
編輯器
使用MonoDevelop這反人類的IDE來編寫Shader居然是讓人滿意的。有語法高亮,無語法提示。
如果習慣VisualStudio,可以如下實現.Shader文件的語法高亮。

下載作者donaldwu自己添加的關鍵詞文件usertype.dat。其包括了Unity ShaderLab的部分關鍵字,和HLSL的所有關鍵字。關鍵字以後持續添加中。
將下載的usertype.dat放到Microsoft Visual Studio xx.xCommonXIDE文件夾下;
打開VS,工具>選項>文本編輯器>文件擴展名,擴展名裏填“shader”,編輯器選VC++,點擊添加;
重啓VS,Done。
Shader
Shader "ShaderLab Tutorials/TestShader"
{
// ...
}
Shader的名字會直接決定shader在material裏出現的路徑

SubShader
Shader "ShaderLab Tutorials/TestShader" {
SubShader
{
//...
}
}
一個Shader有多個SubShader。一個SubShader可理解爲一個Shader的一個渲染方案。即SubShader是爲了針對不同的渲染情況而編寫的。每個Shader至少1個SubShader、理論可以無限多個,但往往兩三個就足夠。
一個時刻只會選取一個SubShader進行渲染,具體SubShader的選取規則包括:

從上到下選取
SubShader的標籤、Pass的標籤
是否符合當前的“Unity渲染路徑”
是否符合當前的ReplacementTag
SubShader是否和當前的GPU兼容

按此規則第一個被選取的SubShader將會用於渲染,未被選取的SubShader在這次渲染將被忽略。

SubShader的Tag
Shader "ShaderLab Tutorials/TestShader" {
SubShader
{
Tags { "Queue"="Geometry+10" "RenderType"="Opaque" }
//...
}
}
SubShader內部可以有標籤(Tags)的定義。Tag指定了這個SubShader的渲染順序(時機),以及其他的一些設置。

"RenderType"標籤。Unity可以運行時替換符合特定RenderType的所有Shader。Camera.RenderWithShader或Camera.SetReplacementShader配合使用。Unity內置的RenderType包括:
"Opaque":絕大部分不透明的物體都使用這個;
"Transparent":絕大部分透明的物體、包括粒子特效都使用這個;
"Background":天空盒都使用這個;
"Overlay":GUI、鏡頭光暈都使用這個;
用戶也可以定義任意自己的RenderType這個標籤所取的值。
應注意,Camera.RenderWithShader或Camera.SetReplacementShader不要求標籤只能是RenderType,RenderType只是Unity內部用於Replace的一個標籤而已,你也可以自定義自己全新的標籤用於Replace。
比如,你爲自己的ShaderA.SubShaderA1(會被Unity選取到的SubShader,常爲Shader文件中的第一個SubShader)增加Tag爲"Distort"="On",然後將"Distort"作爲參數replacementTag傳給函數。此時,作爲replacementShader實參的ShaderB.SubShaderB1中若有也有一模一樣的"Distort"="On"、且這A的材質參數包含B所需材質參數,則此SubShaderB1將代替SubShaderA1用於本次渲染。
具體可參考Rendering with Replaced Shaders
"Queue"標籤。定義渲染順序。預製的值爲
"Background"。值爲1000。比如用於天空盒。
"Geometry"。值爲2000。大部分物體在這個隊列。不透明的物體也在這裏。這個隊列內部的物體的渲染順序會有進一步的優化(應該是從近到遠,early-z test可以剔除不需經過FS處理的片元)。其他隊列的物體都是按空間位置的從遠到近進行渲染。
"AlphaTest"。值爲2450。已進行AlphaTest的物體在這個隊列。
"Transparent"。值爲3000。透明物體。
"Overlay"。值爲4000。比如鏡頭光暈。
用戶可以定義任意值,比如"Queue"="Geometry+10"
"ForceNoShadowCasting",值爲"true"時,表示不接受陰影。
"IgnoreProjector",值爲"true"時,表示不接受Projector組件的投影。

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