Unity-預定義的著色器預處理器宏
Unity 在編譯著色器程序時會定義幾個預處理器宏。
目標平臺
宏:????????????????????????????????????????????????????????????????????????????????????????????目標平臺:
SHADER_API_D3D11????????????
Direct3D 11
SHADER_API_GLCORE????????????
桌面端 OpenGL“核心”(GL 3/4)
SHADER_API_GLES????????????
OpenGL ES 2.0
SHADER_API_GLES3????????????
OpenGL ES 3.0/3.1
SHADER_API_METAL????????????
iOS/Mac Metal
SHADER_API_VULKAN????????????
Vulkan
SHADER_API_D3D11_9X?????
適用于通用 Windows 平臺的 Direct3D 11“功能級別 9.x”目標
SHADER_API_PS4????????????
PlayStation 4。也定義了?SHADER_API_PSSL
。
SHADER_API_XBOXONE????????????
Xbox One
SHADER_API_MOBILE
?是針對所有常規(guī)移動平臺(GLES、GLES3、METAL)定義的。
此外,當目標著色語言為 GLSL 時,還會定義?SHADER_TARGET_GLSL
(對于 OpenGL/GLES 平臺來說始終會定義)。
著色器目標模型
SHADER_TARGET
?被定義為與著色器目標編譯模型匹配的數值(即匹配?#pragma target
?指令)。例如,當編譯到著色器模型 3.0 時,SHADER_TARGET
?為?30
。您可以在著色器代碼中使用此宏來進行條件檢查。例如:
Unity 版本
UNITY_VERSION
?包含 Unity 版本的數值。例如,對于 Unity 5.0.1,UNITY_VERSION
?為?501
。如果您需要編寫使用不同著色器內置功能的著色器,則可以將其用于版本比較。例如,#if UNITY_VERSION >= 500
?預處理器檢查僅在版本為 5.0.0 或更高時可以通過。
編譯的著色器階段
編譯每個著色器階段時會定義預處理器宏?SHADER_STAGE_VERTEX
、SHADER_STAGE_FRAGMENT
、SHADER_STAGE_DOMAIN
、SHADER_STAGE_HULL
、SHADER_STAGE_GEOMETRY
?或?SHADER_STAGE_COMPUTE
。通常,在像素著色器和計算著色器之間共享著色器代碼時,這些宏非常有用,可以解決某些工作必須以略有不同的方式來完成的情況。
平臺差異 helper
不鼓勵直接使用這些平臺宏,因為它們并非始終有助于代碼的未來驗證。例如,如果您正在編寫一個檢查 D3D11 的著色器,您可能希望確保在將來將這項檢查擴展為包含 Vulkan。應改用 Unity 定義的幾個 helper 宏(在?HLSLSupport.cginc
?中):
宏:????????????????????????????????????????????????????????????????????????????????????????用途:
UNITY_BRANCH????
在條件語句之前添加此宏,告知編譯器應將其編譯為實際分支。在 HLSL 平臺上擴展為?[branch]
。
UNITY_FLATTEN????
在條件語句之前添加此宏,告知編譯器應該將其展平以避免實際的分支指令。在 HLSL 平臺上擴展為?[flatten]
。
UNITY_NO_SCREENSPACE_SHADOWS????
在不使用級聯屏幕空間陰影貼圖的平臺(移動平臺)上定義。
UNITY_NO_LINEAR_COLORSPACE????
在不支持線性顏色空間的平臺(移動平臺)上定義。
UNITY_NO_RGBM????
在不使用光照貼圖 RGBM 壓縮的平臺(移動平臺)上定義。
UNITY_NO_DXT5nm????
在不使用 DXT5nm 法線貼圖壓縮的平臺(移動平臺)上定義。
UNITY_FRAMEBUFFER_FETCH_AVAILABLE????
在可使用“幀緩沖顏色提取”功能的平臺(通常為 iOS 平臺 - OpenGL ES 2.0、3.0 和 Metal)上定義。
UNITY_USE_RGBA_FOR_POINT_SHADOWS????
在點光源陰影貼圖使用具有編碼深度的 RGBA 紋理的平臺(其他平臺使用單通道浮點紋理)上定義。
UNITY_ATTEN_CHANNEL????
定義光源衰減紋理的哪個通道包含數據;用于每像素光照代碼。定義為“r”或“a”。
UNITY_HALF_TEXEL_OFFSET????
在將紋理像素映射到像素時需要進行半紋素偏移調整的平臺(例如 Direct3D 9)上定義。
UNITY_UV_STARTS_AT_TOP????
始終定義值為 1 或 0。值為 1 表示在平臺上的紋理之上的紋理 V 坐標為 0。Direct3D 類平臺使用值 1;OpenGL 類平臺使用值 0。
UNITY_MIGHT_NOT_HAVE_DEPTH_Texture????
如果平臺可以通過手動將深度渲染到紋理中來模擬陰影貼圖或深度紋理,則定義此宏。UNITY_PROJ_COORD(a)
給定一個 4 分量矢量,此宏返回一個適合投影紋理讀取的紋理坐標。在大多數平臺上,它直接返回給定值。
UNITY_NEAR_CLIP_VALUE????
定義為近裁剪面的值。Direct3D 類平臺使用 0.0,而 OpenGL 類平臺使用 –1.0。
UNITY_VPOS_TYPE????
定義像素位置輸入 (VPOS) 所需的數據類型:D3D9 上為?float2
,其他為?float4
。
UNITY_CAN_COMPILE_TESSELLATION????
在著色器編譯器“理解”曲面細分著色器 HLSL 語法時定義(當前僅限 D3D11)。
UNITY_INITIALIZE_OUTPUT(type,name)????
將給定_類型_的變量_名稱_初始化為零。
UNITY_COMPILER_HLSL
,?UNITY_COMPILER_HLSL2GLSL
,?UNITY_COMPILER_CG
指示正在使用哪個著色器編譯器來編譯著色器 - 分別為:Microsoft 的 HLSL、HLSL 到 GLSL 轉換器和 NVIDIA 的 Cg。有關更多詳細信息,請參閱著色語言相關文檔。如果您遇到編譯器之間有非常具體的著色器語法處理差異,并希望為每個編譯器編寫不同的代碼,請使用此宏。
UNITY_REVERSED_Z
?- 在使用反轉 Z 緩沖區(qū)的平臺上定義。存儲的 Z 值的范圍是 1 到 0,而不是 0 到 1。
陰影貼圖宏
根據平臺的不同,聲明和采樣陰影貼圖可能會有很大差異。Unity 有幾個宏可幫助解決這個問題:
宏:????????????????????????????????????????????????????????????????????用途:
UNITY_DECLARE_SHADOWMAP(tex)????????
聲明一個名為“tex”的陰影貼圖紋理變量。UNITY_SAMPLE_SHADOW(tex,uv)????
在給定的“uv”坐標處采樣陰影貼圖紋理“tex”(XY 分量是紋理位置,Z 分量是要比較的深度)。返回單個浮點值,陰影項的范圍在 0 到 1 之間。UNITY_SAMPLE_SHADOW_PROJ(tex,uv)????
與上面類似,但是會讀取投影陰影貼圖?!皍v”是一個 float4,所有其他分量除以 .w 來執(zhí)行查找。
__注意:__并非所有顯卡都支持陰影貼圖。請使用?SystemInfo.SupportsRenderTextureFormat?檢查是否支持。
常量緩沖區(qū)宏
Direct3D 11 將所有著色器變量分組為“常量緩沖區(qū)”。Unity 的大多數內置變量已經分組,但對于您自己的著色器中的變量,更加理想的做法是,根據預期的更新頻率將它們放入單獨的常量緩沖區(qū)。
對此,請使用?CBUFFER_START(name)
?和?CBUFFER_END
?宏:
CBUFFER_START(MyRarelyUpdatedVariables)
? ?
float4 _SomeGlobalValue;
CBUFFER_END
紋理/采樣器聲明宏
通常,在著色器代碼中使用?texture2D
?來聲明紋理和采樣器對。 但是在某些平臺(例如 DX11)上,紋理和采樣器是單獨的對象, 并且可能的采樣器最大數量非常有限。Unity 有一些宏來聲明 沒有采樣器的紋理,并使用另一個紋理中的采樣器對紋理進行采樣。 如果您遇到采樣器限制,并且知道幾個紋理實際上可以共享同一個采樣器 (采樣器定義紋理過濾和包裹模式),請使用這些宏。
宏:????????????????????????????用途:
UNITY_DECLARE_TEX2D(name)????????????
聲明紋理和采樣器對。
UNITY_DECLARE_TEX2D_NOSAMPLER(name)????????
聲明不含采樣器的紋理。UNITY_DECLARE_TEX2DARRAY(name)????????
聲明紋理數組采樣器變量。
UNITY_SAMPLE_TEX2D(name,uv)????????
使用給定的紋理坐標從紋理和采樣器對中采樣。
UNITY_SAMPLE_TEX2D_SAMPLER( name,samplername,uv)????
使用另一個紋理中的采樣器 (samplername),從紋理 (name) 中采樣。
UNITY_SAMPLE_TEX2DARRAY(name,uv)????
從具有 float3 UV 的紋理數組中采樣;坐標的 z 分量是數組元素索引。
UNITY_SAMPLE_TEX2DARRAY_LOD(name,uv,lod)????
從具有顯式 Mipmap 級別的紋理數組中采樣。
有關更多信息,請參閱采樣器狀態(tài)文檔。
表面著色器通道指示符
編譯表面著色器時,表面著色器會為各種通道生成大量代碼以產生光照。編譯每個通道時,將定義以下宏之一:
宏:????????????????????????????????????????????????????用途:
UNITY_PASS_FORWARDBASE????
前向渲染基礎通道(主方向光、光照貼圖和 SH)。UNITY_PASS_FORWARDADD????
前向渲染附加通道(每個通道一個光源)。UNITY_PASS_DEFERRED????
延遲著色通道(渲染 G 緩沖區(qū))。
UNITY_PASS_SHADOWCASTER????
陰影投射物和深度紋理渲染通道。
UNITY_PASS_PREPASSBASE????
舊版延遲光照基礎通道(渲染法線和鏡面反射指數)。
UNITY_PASS_PREPASSFINAL????????
舊版延遲光照最終通道(應用光照和紋理)。
禁用自動升級
UNITY_SHADER_NO_UPGRADE
?允許您禁止 Unity 自動升級或修改著色器文件。