什麼是ShaderLab?
" Shaderlab is a friend you can afford." - 尼古拉斯・弗朗西斯( Nicholas Francis)。
Unity Shader是Uniy爲開發者提供的高層級的渲染抽象層,Shaderlab是Uniy提供的編寫 Unity Shader的一種說明性語言。
左圖是未使用unity shader,右圖爲unity shader!
在Unity中,Shader可以分爲三種類型:
- 固定功能着色器(Fixed Function Shader)
對於一些較舊的設備(其GPU僅支持Directx7.0、 OPENGL1.5或 OPENGL ES1.1),它們不支持可編程管線着色器,因此,這時候我們就需要使用固定函數着色器( Fixed Function Shader)來完成渲染。這些着色器住往只可以完成一些非常簡單的效果,已經逐漸被拋棄. - 表面着色器(Surface Shader)
表面着色器是Uniy自己創造的一種着色器代碼類型, 是 Unity對頂點片元着色器的更高一層的抽象。它存在的價值在於, Unity爲我們處理了很多光照細節, 簡化了很多。Unity建議使用表面着色器來編寫和光照有關的Shader。 - 頂點着色器&片段着色器 (Vertex Shader & Fragment Shader)
和OpenGL,Direct3D中的頂點着色器和片段着色器區別不大。頂點片段着色器比表面着色器使用更靈活、更強大,當然也更復雜。
頂點着色器:產生紋理座標,顏色,點大小,霧座標,然後把它們傳遞給裁剪階段。
片段着色器:進行紋理查找,決定什麼時候執行紋理查找,是否進行紋理查找,及把什麼作爲紋理座標。
Unity Shader結構:
Shader "name"
{
//----------屬性-----------
Properties
{
_MainTex("基本紋理",2D)="White"{} //2D紋理
_FloatName("Float Name", Float) = 0.5 //浮點數
_RangeName("Range Name", Range(0.1, 1)) = 0.1 //浮點數 (在指定範圍內)
_ColorName("Color Name", Color) =(1, 1, 1, 1) // 顏色
_VectorName("Vector Name", Vector) =(1, 1, 1, 1) //定義一個四元素的容器(相當於Vector4)屬性
_RectName("Rect name", Rect) = "white"{} //定義長方形(非2次方)紋理屬性
_CubemapName("Cubemap Name", CUBE) = "" {} //定義立方貼圖紋理屬性
}
//----------子着色器(可以多個)----------
SubShader
{
//Pass通道(可以多個):一個Pass就是一次繪製。
Pass
{
//標籤,可選的
[Tags] // Tags { "RenderType" = "Opaque" }
//狀態設置,可選的
[RenderSetup]
//CG代碼塊(每個Pass中都可以包含自定義的Cg代碼,從CGPROGRAM開始到ENDCG結束。)
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
//cpu傳遞到gpu的數據信息
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
//頂點着色器傳遞到片段着色器的數據
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
//頂點着色器
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
//紋理
sampler2D _MainTex;
//片段着色器
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);//獲取紋理顏色值
return col;
}
ENDCG
}
}
//-----------備胎---------
//當上面的所有SubShader在顯卡上都不能運行時,就會啓用最低價的Shader,如下:漫反射shader
Fallback" Diffuse "
}
渲染狀態設置:
Shaderlab提供了一系列渲染狀態的設置指令,這些指令可以設置顯卡的各種狀態,例如是否開啓混合/深度測試等。
例如:ZWrite Off
標籤類型:
Sub Shader的標籤(Tags)是一個鍵值對( Key/Value Pair),它的鍵和值都是字符串類型。這些鍵值對是 Sub Shader和渲染引擎之間的溝通橋樑。
例如:Tags { "RenderType" = "Opaque" }