掌握 ShaderLab 需要循序漸進地學習,結合理論、實踐和工具。以下是一個推薦的學習路徑,幫助你從零基礎逐步進階:
階段一:基礎準備 (理解核心概念與環境)
-
必備知識:
- 編程基礎: 至少熟悉一種編程語言(C# 或 C++ 最佳),理解變量、函數、控制流等概念。Shader 編程邏輯性很強。
- 數學基礎 (尤其重要):
- 向量和矩陣運算: 點積、叉積、矩陣乘法、變換(平移、旋轉、縮放)。這是理解頂點變換、光照計算的基礎。
- 基礎三角函數:
sin
,cos
,tan
等常用于波形、旋轉、周期性動畫。 - 坐標系: 模型空間、世界空間、觀察空間、裁剪空間、屏幕空間。理解頂點如何在不同空間轉換。
- 基礎線性代數: 理解向量空間、線性變換。
- 圖形學基礎概念:
- 渲染管線: 理解 CPU 提交數據 -> 頂點著色器 -> 光柵化 -> 片元著色器 -> 輸出到屏幕 的流程。明確 Vertex Shader 和 Fragment Shader 的職責。
- 光照模型: 環境光、漫反射 (Lambert)、高光反射 (Phong, Blinn-Phong)。理解光線如何與表面交互。
- 紋理映射: UV 坐標、采樣、紋理過濾(點采樣、雙線性、三線性)。
- 混合: Alpha 混合 (Blend) 原理。
-
Unity 基礎:
- 熟悉 Unity 編輯器界面和基本操作。
- 了解材質 (Material) 的概念及其與著色器 (Shader) 的關系。
- 知道如何創建材質球并為其分配著色器。
階段二:入門 ShaderLab (語法與固定函數著色器)
-
ShaderLab 結構:
- 學習
.shader
文件的基本結構:Shader "Path/Name"
:定義著色器在材質下拉菜單中的路徑和名稱。Properties
塊:定義在材質檢視面板中暴露的可調參數(顏色、浮點數、紋理、向量等)。SubShader
塊:針對不同渲染路徑或硬件級別的實現。Pass
塊:一次完整的渲染過程(頂點處理 + 片元處理)。CGPROGRAM
/ENDCG
:包裹 CG/HLSL 代碼塊(可編程著色器)。Tags
:設置渲染順序 ("Queue"
)、渲染類型 ("RenderType"
)、是否投射陰影 ("ForceNoShadowCasting"
) 等。LOD
:細節級別。
- 理解
Properties
如何與 CG/HLSL 代碼中的變量關聯。
- 學習
-
固定函數著色器 (Fixed-Function Shader):
- 目標: 理解早期著色方式,學習 ShaderLab 語法,制作簡單效果。
- 內容:
- 使用
SetTexture
命令進行簡單的紋理采樣和混合。 - 使用
Lighting On
/Material
塊實現簡單的逐頂點光照(漫反射、環境光)。 - 學習
Color
,ColorMaterial
等命令。
- 使用
- 實踐: 編寫一個只顯示紋理的著色器;編寫一個帶簡單頂點光照的紋理著色器。
階段三:核心 - CG/HLSL 與可編程著色器 (Vertex & Fragment Shader)
-
CG/HLSL 語言基礎:
- 語法:變量聲明、數據類型 (
float
,half
,fixed
,float2/3/4
,sampler2D
)、結構體、函數。 - 語義 (Semantics):
POSITION
,NORMAL
,TEXCOORD0
,SV_POSITION
,COLOR
等。理解輸入輸出數據流。 - 常用內置函數:
mul
(矩陣乘法),dot
(點積),cross
(叉積),normalize
,lerp
(線性插值),tex2D
(紋理采樣),saturate
(鉗制到 [0,1]) 等。
- 語法:變量聲明、數據類型 (
-
頂點著色器 (Vertex Shader):
- 職責: 將模型頂點從模型空間變換到裁剪空間(通過 MVP 矩陣)。
- 計算并傳遞數據給片元著色器(如:世界空間位置、法線、UV、頂點顏色等)。
- 實現簡單的頂點動畫(如:波浪、旋轉)。
-
片元著色器 (Fragment Shader / Pixel Shader):
- 職責: 計算每個像素(更準確說是片元)的最終顏色。
- 核心內容:
- 紋理采樣與應用。
- 光照計算: 實現自定義光照模型(Lambert, Phong, Blinn-Phong, 半蘭伯特)。
- 理解
_WorldSpaceLightPos0
,_LightColor0
,UNITY_LIGHTMODEL_AMBIENT
等內置光照變量。 - 法線貼圖 (Normal Mapping):使用切線空間法線擾動表面法線,增加細節。
- 透明與混合 (
Blend
命令)。 - 簡單的屏幕后處理效果基礎(需要結合
OnRenderImage
)。
-
實踐項目 (關鍵!):
- 無光照純色/紋理著色器。
- 自定義漫反射光照著色器(逐頂點/逐像素)。
- 自定義高光(Phong/Blinn-Phong)著色器。
- 紋理 + 法線貼圖著色器。
- 透明著色器(Alpha Blend)。
- 溶解效果 (利用
clip
函數)。 - 簡單的頂點動畫(如旗幟飄動)。
- 邊緣光 (Rim Light) 效果。
階段四:進階技術與優化
-
表面著色器 (Surface Shader):
- 理解: Unity 對光照模型的一種高級封裝。它幫你處理了光照pass、陰影pass、前向/延遲渲染兼容性等復雜問題,你只需關注表面的屬性(反照率、法線、自發光、高光、光滑度、金屬度等)和光照函數。
- 學習:
SurfaceOutput
結構體,surf
函數,自定義光照函數LightingXxxx
。 - 適用場景: 需要標準光照(特別是 PBR)且不想手動處理所有pass的情況。非常常用。
- 實踐: 實現自定義光照模型的表面著色器(如 Toon 卡通著色)。
-
渲染路徑 (Rendering Path):
- 理解前向渲染 (Forward Rendering) 和延遲渲染 (Deferred Rendering) 的區別、優缺點及適用場景。
- 學習如何在 Shader 中處理多光源(前向渲染中的
ForwardAdd
pass)。 - 了解
LightMode
Tag ("ForwardBase"
,"ForwardAdd"
,"Deferred"
)。
-
陰影:
- 理解陰影投射 (
ShadowCaster
pass) 和陰影接收的原理。 - 學習如何讓自定義著色器投射和接收陰影(通常需要定義
ShadowCaster
pass 或使用fallback
)。 - 了解
SHADOW_COORDS
,TRANSFER_SHADOW
,SHADOW_ATTENUATION
宏(用于接收陰影)。
- 理解陰影投射 (
-
屏幕空間效果:
- 使用
GrabPass
抓取屏幕內容。 - 實現簡單的扭曲、全屏模糊、簡單顏色校正等效果。
- 使用
-
光照貼圖與全局光照 (GI):
- 學習
LIGHTMAP_ON
宏和DECLARE_LIGHTMAP_COORDS
/TRANSFER_LIGHTMAP
等宏。 - 讓著色器支持烘焙光照貼圖和實時/烘焙混合光照。
- 學習
-
Shader Graph (可視化工具):
- 目標: 快速搭建效果原型,理解節點化流程,降低復雜 HLSL 代碼編寫負擔。
- 學習: 節點操作、常用節點(數學、紋理、UV、向量、光照節點等)、自定義函數節點、子圖 (Sub Graph)。
- 實踐: 用 Shader Graph 復現之前用代碼寫的效果(如溶解、邊緣光、簡單 PBR)。
-
優化技巧:
- 精度: 合理使用
float
(高精度,32位),half
(中精度,16位),fixed
(低精度,11位) 優化性能和帶寬。 - 計算量: 避免復雜計算在片元著色器中進行(尤其移動平臺),盡量移到頂點著色器或預計算。使用查找紋理 (Lookup Texture)。
- 分支: GPU 不擅長分支預測,盡量避免片元著色器中的復雜分支 (
if/else
)。 - 紋理采樣: 減少采樣次數,使用紋理圖集 (Texture Atlas)。
- Shader Variants: 理解
#pragma multi_compile
和#pragma shader_feature
產生的變體,避免不必要的變體導致包體膨脹。
- 精度: 合理使用
階段五:深入與探索
-
高級光照模型:
- 基于物理的渲染 (PBR): 學習金屬度/粗糙度工作流或鏡面反射/光澤度工作流。理解
Standard
/Standard (Specular setup)
表面著色器背后的原理。 - 次表面散射 (SSS)。
- 各向異性高光。
- 毛發渲染 (Kajiya-Kay)。
- 基于物理的渲染 (PBR): 學習金屬度/粗糙度工作流或鏡面反射/光澤度工作流。理解
-
高級效果:
- 視差貼圖 (Parallax Mapping)。
- 屏幕空間反射 (SSR)。
- 程序化紋理/噪聲生成 (Perlin, Simplex)。
- 體積效果(光線步進 Ray Marching)。
- 卡通渲染 (Cel Shading / NPR)。
- 水體效果。
- 地形混合著色器。
-
Compute Shader:
- 利用 GPU 進行通用計算,處理大量并行數據(物理模擬、粒子系統、圖像處理等)。
-
Shader Debugging:
- 熟練使用
Frame Debugger
。 - 利用
return float4(someValue, 1);
在片元著色器中輸出中間值進行調試。 - 使用
RenderDoc
等外部工具進行深度分析。
- 熟練使用
學習資源推薦
- 官方文檔 (必讀!):
- Unity Manual - Shaders:
https://docs.unity3d.com/Manual/Shaders.html
- Unity Scripting API - ShaderLab:
https://docs.unity3d.com/Manual/SL-Reference.html
- Built-in Shader Include Files (如
UnityCG.cginc
):閱讀源碼是學習內置函數和宏的最佳方式。通常位于[Unity安裝路徑]/Data/CGIncludes
。
- Unity Manual - Shaders:
- 經典書籍/教程:
- 《Unity Shader入門精要》(馮樂樂著) - 中文經典,系統全面。
- 《Unity 2018 Shaders and Effects Cookbook》 - 英文,案例驅動。
- Catlike Coding - Rendering Tutorials (
https://catlikecoding.com/unity/tutorials/rendering/
) - 非常深入、系統的英文教程。 - Ben Cloward’s Shader Development YouTube Channel (
https://www.youtube.com/@BenCloward
) - 大量實用視頻教程。
- 社區:
- Unity Forums (Graphics 板塊):
https://forum.unity.com/forums/graphics.75/
- ShaderToy (
https://www.shadertoy.com/
) - 學習 GLSL 和前沿效果的寶庫(注意語法差異,但思路相通)。 - GitHub:搜索開源項目學習他人代碼。
- Unity Forums (Graphics 板塊):
- 工具:
- Visual Studio / VS Code (with ShaderlabVSCode / Shader Languages Support 插件): 提供語法高亮、自動補全。
- Shader Graph: Unity 內置可視化著色器編輯器。
- Amplify Shader Editor: 強大的第三方可視化著色器編輯器。
- RenderDoc: 強大的圖形調試器。
- Frame Debugger (Unity 內置): 逐幀分析渲染過程。
核心建議
- 動手!動手!動手! 理論必須結合實踐。每學一個概念,立即在 Unity 中寫代碼測試效果。從修改官方內置著色器開始。
- 循序漸進: 不要一開始就追求復雜炫酷的效果。打好數學、圖形學基礎、理解管線、掌握 Vertex/Fragment Shader 是核心。
- 理解而非死記: 理解渲染管線、光照模型、數學變換背后的原理,比記住具體代碼更重要。這樣你才能舉一反三。
- 善用調試工具: Frame Debugger 和
return float4
調試法是你的好朋友。 - 閱讀優秀代碼: Unity 內置著色器源碼 (
CGIncludes
文件夾) 是極佳的學習材料。 - 關注性能: 尤其在移動平臺,時刻考慮優化。了解不同精度類型和計算開銷。
- 利用可視化工具: Shader Graph / Amplify 能幫助你快速理解數據流動和效果搭建,但最終要理解其生成的代碼邏輯。
- 保持耐心和熱情: Shader 學習曲線陡峭,遇到困難是正常的。多查資料,多嘗試,多問(清晰的描述問題)。
遵循這個路徑,持續學習和實踐,你就能逐步掌握 ShaderLab 和 Unity 著色器開發,創造出令人驚嘆的視覺特效!祝你學習順利!