Unity3D Shader 入門知識詳解。
Unity3D Shader 入門知識
Shader(著色器)對很多 Unity 初學者來說像是“黑魔法”。
實際上,Shader 并沒有那么神秘,它本質上就是一段運行在 GPU 上的小程序,用來控制 屏幕上每個像素的顏色和顯示效果。
本文會寫一個最簡單的 Shader,并逐步講解 Shader 的基本結構。
什么是 Shader
在 Unity 中,Shader 是材質的核心,它告訴 GPU 如何去渲染一個物體。
我們平常看到的各種特效(發光、透明、水波、卡通描邊)都是 Shader 在發揮作用。
Unity 的 Shader 常見有三類:
- Surface Shader:Unity 封裝的高層次寫法,適合快速實現光照材質。
- Vertex/Fragment Shader:底層控制方式,可以完全自定義頂點和像素的渲染。
- Shader Graph:可視化編輯,拖拽節點即可拼接 Shader。
本文我們先用 最簡單的 Unlit Shader(無光照)入門。
Shader 的基本結構
在 Unity 中,一個最基礎的 Shader 結構長這樣:
Shader "Custom/SimpleColor"
{Properties{_Color ("Main Color", Color) = (1,1,1,1)}SubShader{Tags { "RenderType"="Opaque" }Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"fixed4 _Color;struct appdata{float4 vertex : POSITION;};struct v2f{float4 pos : SV_POSITION;};v2f vert (appdata v){v2f o;o.pos = UnityObjectToClipPos(v.vertex);return o;}fixed4 frag (v2f i) : SV_Target{return _Color;}ENDCG}}
}
代碼解讀
命名
Shader "Custom/SimpleColor"
每個 Shader 都需要一個唯一的名字,格式通常是 Shader "路徑/名字"
。
這里并不是文件路徑,而是 Unity 內部的命名空間。
在材質球 (Material) 的 Shader 下拉菜單 里,這個名字會決定 Shader 的顯示位置。
Properties 塊
Properties
{_Color ("Main Color", Color) = (1,1,1,1)
}
這里定義了材質面板中可調的屬性。
_Color
:變量名(在 Shader 代碼里使用)"Main Color"
:在 Inspector 面板顯示的名字Color
:屬性類型(1,1,1,1)
:默認值(RGBA = 白色)
SubShader 與 Pass
SubShader
:真正的渲染邏輯寫在這里。Unity 會根據顯卡選擇合適的 SubShader。Pass
:一次渲染指令。復雜 Shader 可能包含多個 Pass,比如一次渲染邊緣,一次渲染本體。
Tags
Tags { "RenderType"="Opaque" }
它是一個 鍵值對 集合,用來告訴 Unity 的渲染管線,這個 Shader 應該被如何分類、排序和處理。
"RenderType"
是 Unity 內置的一個 Shader Tag,用于描述 材質的大類渲染方式。
常見取值有:
"Opaque"
:不透明物體(默認)"Transparent"
:透明物體(如玻璃、粒子、UI)"TransparentCutout"
:透明裁剪物體(如樹葉、圍欄,透明部分直接裁掉,沒有半透明)
這里使用 "Opaque"
,Unity 會把它放到 不透明隊列(Queue = Geometry, 2000 左右) 里進行渲染。
CGPROGRAM 塊
這是 HLSL/CG 代碼的區域,包裹在 CGPROGRAM 和 ENDCG 之間。
#pragma vertex vert
:指定頂點著色器函數(vert)#pragma fragment frag
:指定片元著色器函數(frag)#include "UnityCG.cginc"
:引入 Unity 提供的一個 HLSL 公共函數/宏庫,相當于 C# 里的using
,例如下面用到的UnityObjectToClipPos
就是這個庫里的函數,把 模型空間 轉換成 裁剪空間,幾乎每個 Shader 頂點著色器都要用到。
fixed4 _Color;
在代碼區域定義的 _Color
變量,使用的是 Properties
定義的 _Color
屬性,名稱要一致才能獲取到。
頂點數據 appdata
struct appdata
{float4 vertex : POSITION;
};
appdata
是一個 輸入結構體,表示從 CPU → GPU 傳遞過來的信息(網格頂點數據),是 GPU 渲染管線的入口數據。
這里的 語義標識符(: POSITION
)告訴 GPU,vertex
對應的是頂點坐標。
Mesh 的每個頂點都會生成一個 appdata
,送入頂點著色器。
頂點著色器 vert
struct v2f
{float4 pos : SV_POSITION;
};v2f vert (appdata v)
{v2f o;o.pos = UnityObjectToClipPos(v.vertex);return o;
}
- 輸入
appdata
:包含了模型的頂點數據(位置、法線、UV 等)。 UnityObjectToClipPos
:把模型空間的坐標轉換到屏幕空間(必須操作)。- 輸出
v2f
:傳遞給片元著色器的數據(同appdata
,是一個結構體)。
片元著色器 frag
fixed4 frag (v2f i) : SV_Target
{return _Color;
}
frag
決定屏幕上這個像素最終是什么顏色。- 這里直接返回
_Color
,所以整個模型就是一塊純色。
在 Unity 中測試
新建一個 Shader 文件,命名為 SimpleColor
,粘貼上面的代碼。
新建一個 材質(Material),把 Shader 設置為 Custom/SimpleColor
。
創建一個 Cube,把材質拖到 Cube 上。
在 Inspector 面板調整 Main Color
,模型就會變成對應的顏色。