1. 程式人生 > >Shader山下(二十)編譯指令(Compilation Directives)

Shader山下(二十)編譯指令(Compilation Directives)

Shader中,編譯指令分為兩種,一種是常規的編譯指令,也就是頂點片元著色器(Vetex & Fragment Shader)使用的編譯指令,另一種就是表面著色器(Surface Shader)使用的編譯指令。二者都使用#pragma語句來編寫,並且都需要寫在CGPROGRAM和ENDCG之間。區別在於,VF編譯指令寫在Pass裡面,而表面著色器編譯指令寫在SubShader裡面,表面著色器會自行編譯到多通道里去,並且需要使用#pragma surface …指令來標識這是一個表面著色器。

VF編譯指令:

#pragma vertex name 編譯name函式為頂點著色器
#pragma fragment name
編譯name函式為片元著色器
#pragma geometry name 編譯name函式為DX10的幾何著色器
注:會自動開啟#pragma target 4.0
#pragma hull name 編譯name函式為DX10的殼著色器
注:會自動開啟#pragma target 5.0
#pragma domain name 編譯name函式為DX10的域著色器
注:會自動開啟#pragma target 5.0
#pragma target name
#pragma only_renderers space_separated_names 只為指定的渲染平臺渲染著色器
包括下列值:
d3d9:Direct3D 9
d3d11:Direct3D 11/12
glcore:OpenGL 3.x/4.x
gles:OpenGL ES 2.0
gles:OpenGL ES 3.x
metal:IOS&Mac Metal
d3d11_9x:Direct3D 11 9.x特性等級一般用於WSA平臺
xbox360:Xbox 360
xboxone:Xbox One
ps4:PlayStation 4
psp2:PlayStation Vita
n3ds:Nintendo 3DS
wiiu:Nintendo Wii U
#pragma exclude_renderers space_separated_names 排除指定的渲染平臺
引數同上
#pragma enable_d3d11_debug_symbols 生成d3d11的除錯資訊
可以在VS2012(或以上)使用圖形偵錯程式除錯shader
#pragma hardware_tier_variants renderer_name

表面著色器編譯指令,只有#pragma surface一個,寫法:

#pragma surface surfFunc lightingModel [optional params]

但是可以為這條指令配置不同的選項:

surfaceFunction(必選) 表面著色器函式
lightModel(必選) 光照模型函式,內建模型:
Standard:基於物理的漫反射模型
StandardSpecular:基於物理的高光模型
Lambert:不基於物理的漫反射模型
BlinnPhong:不基於物理的高光模型
也可以自己寫,命名規則:Lighting...
...為在編譯指令裡填寫的名稱
例如#pragma surface surf Custom
光照模型函式名就要寫成:
LightingCustom
具體參考表面著色器中的自定義光照模型
alpha或者alpha:auto 透明度混合
對於簡單的光照模型(例如Lambert和BlinnPhong)使用alpha:fade
對於基於物理的光照模型使用alpha:premul
alpha:blend 透明度混合
alpha:premul 預乘透明度混合
alphatest:variable_name 透明度測試,並使用variable_name作為裁切閾值
keepalpha 對於預設的不透明Shader,會無視光照模型返回的透明度值,直接把1.0寫入Alpha通道。
使用keepalpha選項,允許在不透明Shader裡保留光照模型返回的透明度值。
decal:add 附加的貼花shader,這意味著物件在其他表面的上面並使用新增方法進行混合。
decal:blend 半透明貼花shader,這意味著物件在其他表面的上面並使用透明度方法進行混合。
vertex:vertex_function 自定義頂點函式
finalcolor:color_function 自定義的最終顏色修改函式
finalgbuffer:gbuffer_function 自定義的改變GBuffer內容的延遲路徑
finalprepass:prepass_function 自定義的預通道基礎路徑
addshadow 生成一個陰影投射通道
一般用於自定義頂點函式,這樣的話,就可以對陰影投射使用程式化的頂點動畫
一般情況下,shader並不需要任何特殊的陰影處理,因為它們可以使用Fallback裡的陰影投射通道
fullforwardshadows 支援前向渲染路徑裡的所有光照陰影
預設情況下只支援一個平行光的陰影
如果需要點光源(point)或者聚光燈(spot)的陰影,那麼就要使用這個選項
tessellate:tessellate_function 使用DX11的GPU鑲嵌,tessellate_function計算鑲嵌引數
參考表面著色器鑲嵌
exclude_path:path
不生成指定渲染路徑的通道
可選項:
deferred
forwad
prepass
noshadow 禁用陰影
noambient 禁用環境光或者光探頭
novertexlights 禁用前向渲染中的光探頭或者每頂點光照
nolightmap 禁用所有的光照貼圖
nodynlightmap 禁用動態光照貼圖
nodirlightmap 禁用平行光照貼圖
nofog 禁用內建霧效
nometa 不生成元通道
光照貼圖和動態全域性光照使用元通道來提取表面資訊
noforwardadd 禁用前置渲染的附加通道
這樣就讓shader支援一個完全平行光,而其他的光使用每頂點或者SH(球諧函式)計算
同樣讓shader變得更輕
softvegetation 在Quality Setting裡的Soft Vegetation被開啟的時候,才會被渲染
interpolateview 在頂點著色器中計算檢視方向並插入它(預設在畫素著色器中計算)
這樣使得Shader變得更快,不過需要多使用一個紋理插值。
halfasview 傳遞半形向量給光照模型(預設是檢視向量)
會在每個頂點計算並歸一化半形向量
這樣更快,但是並不完全正確。
approxview 5.0中被interpolateview取代
dualforward 在前向渲染路徑中使用雙光照貼圖