1. 程式人生 > >Unity著色器常用關鍵字及屬性

Unity著色器常用關鍵字及屬性

看了好多次shader,不過還是感覺無從下手的去寫shader,然後看shader的效果

個人認為還是因為shader基礎打得不夠紮實,顧特意再重溫shader相關書籍的時候,看見有些常用關鍵字時,把他記錄下來

希望這對學習unity shader的同學來說有些用

Shader

  • 這是shader的根命令

SubShader

  • 這個是子著色器,一個Shader裡面可以有多個SubShader

Properties

  • 屬性塊

常用屬性

語法 說明
name(“display name”,Range(min,max)=number) 定義一個範圍值
name(“display name”,Color=(number,number,number,number) 定義顏色,number取0~1
name(“display name”,2D)=”name”{option} 定義2D紋理,預設值:”white”,”black”,”gray”,”bump”
name(“display name”,Rect)=”name”{option} 定義矩形紋理(非2的n次冪),預設值為2D紋理屬性
name(“display name”,Cube)=”name”{option} 定義立方體紋理,預設值同位2D紋理
name(“display name”,Float)=number 定義一個浮點數
name(“display name”,Vector)=(number,number,number,number) 定義四維向量

紋理屬性選項(即2D等屬性的{option})

選項名稱 說明
TexGen 自動生成紋理座標時的模式,可以為:ObjectLiner、EyeLinear、SphereMap、CubeMap、CubeNormal
LightmapMode 光照貼圖模式,如果給出這個選項,紋理會被渲染器的光線貼圖所影響,即紋理不能被應用在材質中,而是使用渲染器中的設定

Tags

  • Queue 佇列標籤

Tags {“Queue”=”Transparent”}

佇列名稱 說明
Background 後臺,這個渲染佇列在所有渲染佇列之前渲染,被用於天空盒之類的物件(1000)
Geometry 幾何體,這個是預設佇列,被用於大多數物件,不透明的幾何體使用這個佇列(2000)
Transparent 透明,在幾何體佇列之後渲染,採用由後到前的次序,任何採用alpha混合的物件(不對深度緩衝產生寫操作的著色器)應該在這裡渲染(如玻璃,粒子等)(3000)
Overlay 覆蓋,這個渲染佇列用於實現疊加效果,任何需要最後渲染的物件應該放置在此處(如鏡頭光暈)(4000)
  • IgnoreProjector 忽略投影標籤

Pass

  • 每個通道都能使幾何體被渲染一次,一個Subshader裡面可以有多個Pass

兩個特殊通道

通道名稱 語法 說明
UsePass UsePass “Shader/Name” 插入所有來自給定著色器中的給定名字的通道,Shader為著色器的名字,Name是通道的名字
GrabPass GrabPass{[“紋理名”]} 捕獲螢幕到一個紋理,該紋理通常使用在靠後的通道中,”紋理名”是可選的

UsePass例子:
UsePass “Specular/BASE”
Name “MyPassName”
使用Specular/BASE這個Pass,並在當前shader中重新命名為MyPassName使用
所有通道名字都是大寫開頭,因此UsePass必須使用大寫開頭的名字來書寫索引

GrabPass捕獲當前螢幕內容到一個紋理中,紋理能在後續通道中通過_GrabTexture進行訪問

通道渲染設定命令

命令 說明
Material{材質塊} 定義一個使用頂點光照管線的材質
Lighting 開關狀態 開啟或關閉頂點光照。開關狀態值為On或Off
Cull 裁剪模式 設定裁剪模式,裁剪模式有Back、Front、Off
ZTest 測試模式 設定深度測試模式。測試模式有Less、Greater、LEqual、GEqual、Equal、NotEqual、Always
ZWrite 開關狀態 開啟或關閉深度緩衝,開關值為On或Off
Fog{霧塊} 設定霧引數
AlphaTest 測試模式< alpha測試值 > 開啟alpha測試,測試模式有Less、Greater、LEqual、GEqual、Equal、NotEqual、Always
Blend 混合模式 設定alpha混合模式,混合模式有SourceBlendMode、DestBlendMode
Color <顏色> 設定當頂點光照關閉時使用的顏色
ColorMask 顏色值 設定顏色遮罩,顏色值可以使用RGB或A或0或任何R、G、B、A的組合,設定為0將關閉所有顏色通道的渲染
Offset 偏移因子,偏移單位 設定深度偏移,這個命令僅接受常數引數
SeparateSpecular 開關狀態 開啟或關閉頂點光照相關的鏡面高光顏色。開關狀態的值為On或Off
ColorMaterial 顏色集 當計算頂點光照時使用頂點顏色,顏色集可以是AmbientAndDiffuse,也可以是Emission

SetTexture

  • 設定紋理,格式為SetTexture [紋理屬性名] {紋理塊}

混合

  • 混合是用來製作透明物體的

    常用混合只能在RGBA模式下進行,物體的繪製順序會影響到OpenGL的混合處理

    Blend常用語法如下:
    • Blend Off
    • 關閉混合
    • Blend 源因子 目標因子
    • 配置並開啟混合,計算產生的顏色和源因子相乘,顏色緩衝中的顏色和目標因子相乘,然後兩個顏色相加
    • Blend 源因子 目標因子,源因子A 目標因子A
    • 源因子,目標因子和上面相同,但是源因子A,目標因子A這些因子使用alpha通道進行混合
    • BlendOp 操作
    • 不是將加入的顏色混合在一起,而是對他們做一些操作,主要操作指令有Min(最小值)、Max(最大值)、Sub(求和)、RevSub

關於混合因子

OpenGL紅寶書上的解釋為:

源因子:就是當前的貼圖,或光照計算後生成的顏色值

目標因子:就是顯示器中的幀快取的圖

常用混合因子(對源因子和目標因子都有效)如下:

混合因子 說明
One 值為1,使用此設定來讓源或是目標顏色完全地通過
Zero 值為0,使用此設定來刪除源或目標值
SrcColor 此階段的值是乘以源顏色的值
SrcAlpha 此階段的值是乘以源alpha的值
DstColor 此階段的值是乘以幀緩衝區目標顏色的值
DstAlpha 此階段的值是乘以幀緩衝區目標alpha的值
OneMinusSrcColor 此階段的值是乘以(1-源顏色)
OneMinusSrcAlpha 此階段的值是乘以(1-源alpha)
OneMinusDstColor 此階段的值是乘以(1-目標顏色)
OneMinusDstAlpha 此階段的值是乘以(1-目標alpha)



以下是常見的混合型別:

  • Blend SrcAlpha OneMinusSrcAlpha //混合
  • Blend One One //混合相加
  • Blend One OneMinusDstColor //柔和相加混合
  • Blend DstColor Zero //相乘混合
  • Blend DstColor SrcColor //2倍相乘混合

通道標籤

通道標籤只能在通道(而不是子著色器)中使用

  • LightMode
    • 光照模式標籤,它定義了光照管線中的通道的角色。比較少用,大多數情況下需要和光照進行互動的著色器會被寫成表面著色器

常用光照模式標籤表如下:

標籤 說明
Always 總是渲染,沒有光照應用
ForwardBase 環境光,主要的定向光,頂點/SH光被應用
ForwardAdd 附加的逐畫素光照被應用。每個光照1個通道
PrepassBase 渲染法線/鏡面指數
PrepassFinal 使用紋理,光照和自發光混合出最終的顏色
Vertex 當物體沒有光照對映使用頂點光照渲染,所有頂點光照被應用
VertexLMRGBM 當物體有光照對映時使用頂點光照渲染,在平臺上光照對映是RGBM編碼
VertexLM 當物體有光照對映時使用頂點光照渲染,在平臺上光照對映是double-LDR編碼(移動平臺,以及老師CPU)
ShadowCaster 將物體當做陰影產生者來渲染
ShadowCollector 為了正向渲染路徑將物件的陰影收集到螢幕空間緩衝區中

- RequireOptions
- 當某些額外條件滿足時,該通道才會被渲染,它的值是SoftVegetation,需要在Quality Settings中開啟SoftVegetation才渲染通道

Fallback

  • 降級,如果沒有子著色器能使用,將執行降級著色器,用法如下:
  • Fallback “著色器名” //迴歸到指定著色器
  • Fallback Off //不降級,也不會出現任何出錯報警,沒有子著色器也會繼續執行

Category

  • 分類是渲染命令的邏輯組,大多數情況下用於繼承渲染狀態

#pragma surface 表面函式 光照模式 [可選引數]

  • 表面函式
    表明那些CG函式中有表面著色器的程式碼,這個函式的格式如下:
    void surf(Input IN,inout SurfaceOutpur o)

  • 光照模式
    在光照模式中使用,內建的光照模式有Lamberr(漫反射)和BlinnPhong(高光)

  • 可選引數
    可選引數列表如下:

可選引數 說明
alpha Alpha混合模式,使用它可以寫出用以渲染半透明效果的著色器
alphatest:VariableName Alpha測試模式,使用它可以寫出鏤空效果的著色器。樓口大小的變數(VariableName)是一個float型的變數
vertex:VertexFunction 自定義的頂點函式,VertexFunction為函式名
finalcolor:ColorFunction 自定義的最終顏色函式,ColorFunction為函式名
exclude_path:prepass或exclude_path:forward 使用指定的渲染路徑,不需要生成通道
addshadow 新增陰影投射並且集合通道,通常用於自定義頂點的修改,使陰影也能投射在任何過程的頂點動畫上
dualforward 在正向(forward)渲染路徑中使用雙重光照貼圖(dual lightmap)
fullforwardsshadows 在正向(forward)渲染路徑中支援所有陰影型別
decal:add 新增貼花著色器
decal:blend 混合半透明的貼花著色器
softvegetation 使表面著色器僅能在Soft Vegetation開啟時進行渲染
noambient 不使用任何環境光照(ambient lighting)或者球面調和光照(spherical harmonics lights)
novertexlights 在正向渲染(Forward rending)中不使用球面調和光照(spherical harmonics lights)或每頂點光照(per-vertex lights)
nolightmap 在這個著色器上禁用光照貼圖(lightmap)
nodirlightmap 在這個著色器上禁用方向光照貼圖(directional lightmap)
noworwardadd 禁用正向渲染新增通道,這會使這個著色器支援一個完整的方向光和所有逐頂點/SH計算的光照
approxview 當著色器有需要的時候,計算每個頂點,而不是每個畫素的方向,這樣更快,但是當攝像機接近表面時,檢視方向不完全正確
halfasview 在光照函式中傳遞進來的是half-direction向量,而不是檢視方向向量,Half-direction計算且將每個頂點標準化,這樣更快,但不完全正確



標準的表面著色器輸出結構體如下:
struct SurfaceOutput {
half3 Albedo; //反射光顏色
half3 Normal; //法線
half3 Emission; //自發光,用於增強物體自身的亮度,使之看起來好像可以自己發光
half Specular; //鏡面高光
half Gloss; //光澤度
half Alpha; //透明度
};

表面著色器的輸入結構體Input包含著所有著色器所需要的紋理座標和附加值
紋理座標必須在紋理名稱前面加上”uv”,或者以”uv2”作為頭命名來使用第二個紋理座標集
附加值按需要加入Input中,常用附加值如下所示:

附加值 說明
float3 viewDir 檢視方向,為了計算視差、邊緣光照等效果,Input需要包含檢視方向
float4 with COLOR semantic 每個頂點顏色的插值
float4 screenPos 螢幕空間中的位置,為了獲得反射效果,需要包含螢幕座標
float3 worldPos 世界座標
float3 worldRefl 世界空間中的反射向量。如果表面著色器不寫入法線(o.Normal)引數,將包含這個引數
float3 worldNormal 世界空間中的法線向量。如果表面著色器不寫入法線(o.Normal)引數,將包含這個引數
float3 worldRefl;INTERNAL_DATA 內部資料。如果表面著色器寫入了o.Normal,將包含世界反射向量。為了得到基於每個畫素的法線貼圖的反射向量需要使用世界反射向量(WorldReflection(IN,o.Normal))
float3 wroldNormal;INTERNAL_DATA 內部資料。如果表面著色器寫入了o.Normal,將包含世界法線向量。為了得到基於每個畫素的法線貼圖的法線向量需要使用世界反射向量(WorldReflection(IN,o.Normal))

RenderType

在一個子著色器的Tags中可以設定RenderType,格式如:
Tags {“RenderType” = “Opaque”}
而RenderType的引數如下所示:

  • Opaque: 用於大多數著色器(法線著色器、自發光著色器、反射著色器以及地形的著色器)。
  • Transparent:用於半透明著色器(透明著色器、粒子著色器、字型著色器、地形額外通道的著色器)。
  • TransparentCutout: 蒙皮透明著色器(Transparent Cutout,兩個通道的植被著色器)。
  • Background: Skybox shaders. 天空盒著色器。
  • Overlay: GUITexture, Halo, Flare shaders. 光暈著色器、閃光著色器。
  • TreeOpaque: terrain engine tree bark. 地形引擎中的樹皮。
  • TreeTransparentCutout: terrain engine tree leaves. 地形引擎中的樹葉。
  • TreeBillboard: terrain engine billboarded trees. 地形引擎中的廣告牌樹。
  • Grass: terrain engine grass. 地形引擎中的草。
  • GrassBillboard: terrain engine billboarded grass. 地形引擎何中的廣告牌草。

頂點片元著色器

頂點片元著色器不使用燈光互動,實際著色器程式碼用CG或HLSL語言編寫,嵌入在著色器的通道塊中,常用編譯指令表如下所示:

編譯指令 說明
pragma vertex 宣告以name為名字的函式是頂點程式
pragma fragment 宣告以name為名字的函式是片元程式
pragma fragmentoption 新增選項到編譯的OpenGL片元程式,通過OpenGL的ARB_fragment_program可以查詢到所允許的規範的選項列表,這個指令對頂點程式或者不是以OpenGL為編譯目標的程式無效
pragma target 著色器目標編譯
pragma only_renderers 僅用給定的渲染器編譯著色器。預設情況下用所有的渲染器都編譯著色器。當選擇多個渲染器時用空格隔開
pragma exclude_renderers 不用給定的渲染器編譯著色器。預設情況下用所有的渲染器都編譯著色器。當選擇多個渲染器時用空格隔開
pragma glsl 用桌面OpenGL平臺編譯著色器時,將Cg/HLSL轉換成GLSL而不是預設的ARB頂點片元著色器



在only_renderers和exclude_renderers中的渲染器如下:

渲染器 渲染器指令程式碼
Direct3D 9 d3d9
OpenGL opengl
OpenGL ES 2.0 gles
Xbox 360 xbox360
PlayStation 3 ps3
Flash flash



使用方法:#pragma only_renderers opengl

注意:每個頂點片元著色器必須包含一個頂點程式或者片元程式(或兩者兼有),因此需要一個#pragma vertex命令或者#pragma fragment命令(或兩者兼有)

頂點結構成員

成員 說明
float4 vertex 頂點位置
float3 normal 頂點法線
float4 texcoord 第一UV座標
float4 texcoord1 第二UV座標
float4 tangent 切線向量(用在法線貼圖中)
float4 color 每個頂點(per-vertex)顏色