Стандартные шейдерные предпроцессорные макросы
Unity defines several preprocessor macros when compiling shader programs.
Целевая платформа
Macro: | Целевая платформа |
---|---|
* SHADER_API_D3D11 - Direct3D 11 для ПК |
Direct3D 9 |
* SHADER_API_D3D11 - Direct3D 11 для ПК |
Direct3D 11 |
SHADER_API_GLCORE |
* SHADER_API_OPENGL - OpenGL для ПК |
SHADER_API_OPENGL |
* SHADER_API_OPENGL - OpenGL для ПК |
* SHADER_API_OPENGL - OpenGL для ПК |
OpenGL ES 2.0 |
* SHADER_API_OPENGL - OpenGL для ПК |
OpenGL ES 3.0/3.1 |
* SHADER_API_OPENGL - OpenGL для ПК |
iOS/Mac Metal |
* SHADER_API_D3D11 - Direct3D 11 для ПК |
* SHADER_API_D3D11_9X - Direct3D 11 для Windows RT |
* SHADER_API_OPENGL - OpenGL для ПК |
PlayStation 4 |
* SHADER_API_OPENGL - OpenGL для ПК |
Xbox One |
* SHADER_API_OPENGL - OpenGL для ПК |
PlayStation 3 |
* SHADER_API_OPENGL - OpenGL для ПК |
Xbox 360 |
* SHADER_API_OPENGL - OpenGL для ПК |
PlayStation Vita |
* SHADER_API_OPENGL - OpenGL для ПК |
Nintendo WiiU |
SHADER_API_MOBILE
is defined for all general mobile platforms (GLES, GLES3, METAL, PSP2).
В случае, если GLSL выбран как целевой язык программирования шейдеров, дополнительно определяется SHADER_TARGET_GLSL
(всегда true, если определен SHADER_API_GLES
; и может быть true для SHADER_API_OPENGL
при использовании #pragma glsl
).
SHADER_TARGET
is defined to a numeric value that matches the shader target compilation model (i.e. matching #pragma target
directive). For example, SHADER_TARGET
is 30
when compiling into shader model 3.0. You can use it in shader code to do conditional checks. For example:
#if SHADER_TARGET < 30
// less than shader model 3.0:
// very limited shader capabilities, do some approximation
#else
// decent capabilities, do a better thing
#endif
UNITY_VERSION
contains the numeric value of the Unity version. For example, UNITY_VERSION
is 501
for Unity 5.0.1. This can be used for version comparisons if you need to write shaders that use different built-in shader functionality. For example, a #if UNITY_VERSION >= 500
preprocessor check will only pass on versions 5.0.0 or later.
Вспомогательные макросы для определения различий в платформах
Использовать представленные выше макросы для определения различных платформ не рекомендуется, так как в последствии может потребоваться изменение условий компиляции. Например, если вы пишете шейдер, который проверяет, определен ли D3D9, то, возможно, в будущем проверку условия придется расширить до D3D11. Вместо этого, Unity предлагает набор вспомогательных макросов (в HLSLSupport.cginc
)
Macro: | Use: |
---|---|
UNITY_BRANCH |
Add this before conditional statements to tell the compiler that this should be compiled into an actual branch. Expands to [branch] when on HLSL platforms. |
UNITY_FLATTEN |
Add this before conditional statements to tell the compiler that this should be flattened to avoid an actual branch instruction. Expands to [flatten] when on HLSL platforms. |
UNITY_NO_SCREENSPACE_SHADOWS |
Defined on platforms that do not use cascaded screenspace shadowmaps (mobile platforms). |
UNITY_NO_LINEAR_COLORSPACE |
Defined on platforms that do not support Linear color space (mobile platforms). |
UNITY_NO_RGBM |
Defined on platforms where RGBM compression for lightmaps is not used (mobile platforms). |
UNITY_NO_DXT5nm |
Defined on platforms that do not use DXT5nm normal-map compression (mobile platforms). |
UNITY_FRAMEBUFFER_FETCH_AVAILABLE |
Defined on platforms where “framebuffer color fetch” functionality can be available (generally iOS platforms - OpenGL ES 2.0, 3.0 and Metal). |
UNITY_USE_RGBA_FOR_POINT_SHADOWS |
Defined on platforms where point light shadowmaps use RGBA textures with encoded depth (other platforms use single-channel floating point textures). |
UNITY_ATTEN_CHANNEL |
* UNITY_ATTEN_CHANNEL - какой канал текстуры хранит данные о затухании света; используется при пиксельном освещении. Определен как ‘r’, либо ‘а’. |
UNITY_HALF_TEXEL_OFFSET |
* UNITY_HALF_TEXEL_OFFSET - определен в платформах, требующих смещения в половину текселя для правильного соотнесения текселей с пикселями (например в Direct3D 9). |
UNITY_UV_STARTS_AT_TOP |
* UNITY_UV_STARTS_AT_TOP - всегда определяется как 0 или 1; на платформах, в которых начало отсчета текстурной координаты V находится “сверху” текстуры, значение равно единице. Платформы на Direct3D используют значение 1; платформы на OpenGL используют значение 0. |
UNITY_MIGHT_NOT_HAVE_DEPTH_TEXTURE |
* UNITY_MIGHT_NOT_HAVE_DEPTH_TEXTURE - определено для платформ, в которых есть возможность эмуляции карт теней или карт глубины с помощью отрисовки карты глубины в текстуру. |
UNITY_PROJ_COORD(a) |
* UNITY_PROJ_COORD(a) - с помощью предоставленного четырехкомпонентного вектора вычислить текстурную координату, подходящую для проекции текстур. На большинстве платформ будет возвращено исходное значение. |
UNITY_NEAR_CLIP_VALUE |
* UNITY_NEAR_CLIP_VALUE - значение ближней плоскости отсечения; в платформах на Direct3D используется значение 0.0, в OpenGL используется –1.0 |
UNITY_VPOS_TYPE |
Defines the data type required for pixel position input (VPOS): float2 on D3D9, float4 elsewhere. |
UNITY_CAN_COMPILE_TESSELLATION |
* UNITY_CAN_COMPILE_TESSELLATION - определен, когда шейдерный компилятор “понимает” синтаксис шейдера тесселяции в HLSL (на данный момент только для D3D11). |
UNITY_INITIALIZE_OUTPUT(type,name) |
* UNITY_INITIALIZE_OUTPUT(type,name) - инициализировать переменную name с типом type, и присвоить ей значение нуля. |
UNITY_COMPILER_HLSL , UNITY_COMPILER_HLSL2GLSL , UNITY_COMPILER_CG
|
* UNITY_COMPILER_HLSL , UNITY_COMPILER_HLSL2GLSL , UNITY_COMPILER_CG - определяет, какой из шейдерных компиляторов используется. Microsoft HLSL (для DX11, Xbox360, WinRT), транслятор HLSL в GLSL (для iOS/Android и OpenGL на ПК, в случае с #pragma glsl) и Cg от NVIDIA (для D3D9 и не GLSL OpenGL на ПК) соответственно. Используйте в случае, если Вы имеете дело с очень специфичным синтаксисом шейдеров, отличающимся для разных компиляторов, и хотите написать различный код для каждого компилятора. |
Макросы для работы с картами теней
Объявление и использование карт теней может существенно отличаться в зависимости от выбранной платформы, поэтому Unity предлагает набор вспомогательных макросов:
Macro: | Use: |
---|---|
UNITY_DECLARE_SHADOWMAP(tex) |
* UNITY_DECLARE_SHADOWMAP(tex) - объявляет текстуру карты теней в виде переменной с именем “tex” |
UNITY_SAMPLE_SHADOW(tex,uv) |
* UNITY_SAMPLE_SHADOW(tex,uv) - находит значение затенения (в диапазоне 0..1) в карте теней с именем “tex” по координате “uv” (компоненты XY служат для поиска по текстуре, компонент Z представляет собой буфер глубины для возможности проведения сравнений). |
UNITY_SAMPLE_SHADOW_PROJ(tex,uv) |
* UNITY_SAMPLE_SHADOW_PROJ(tex,uv) - аналогично предыдущему, но производит проецируемое чтение текстуры. Координата “uv” — это float4, все остальные компоненты делятся на .w для выполнения поиска. |
Макросы буферов констант
Direc3D 11 группирует все переменные шейдеров в “буфер констант”. Большинство встроенных в Unity переменных сгруппированы по умолчанию, но для собственных шейдеров более оптимальным подходом является распределение переменных по отдельным буферам констант в зависимости от предполагаемой частоты обновлений.
Для этого можно использовать макрос CBUFFER_START(name)
и CBUFFER_END
:
CBUFFER_START(MyRarelyUpdatedVariables)
float4 _SomeGlobalValue;
CBUFFER_END
Usually you would use texture2D
in shader code to declare a texture and sampler pair.
However on some platforms (such as DX11), textures and samplers are separate objects,
and maximum possible sampler count is quite limited. Unity has some macros to declare
textures without samplers, and to sample a texture using a sampler from another texture.
Use this if you end up running into sampler limits, and you know that several of your
textures can in fact share a sampler (sampler defines texture filtering and wrapping modes).
Macro: | Use: |
---|---|
UNITY_DECLARE_TEX2D(name) |
* UNITY_DECLARE_SHADOWMAP(tex) - объявляет текстуру карты теней в виде переменной с именем “tex” |
* UNITY_DECLARE_SHADOWMAP(tex) - объявляет текстуру карты теней в виде переменной с именем “tex” |
* UNITY_DECLARE_SHADOWMAP(tex) - объявляет текстуру карты теней в виде переменной с именем “tex” |
UNITY_DECLARE_TEX2DARRAY(name) |
Declares a texture array sampler variable. |
UNITY_SAMPLE_TEX2D(name,uv) |
Sample from a texture and sampler pair, using given texture coordinate. |
UNITY_SAMPLE_TEX2D_SAMPLER( name,samplername,uv) |
Sample from texture (name), using sampler from another texture (samplername). |
UNITY_SAMPLE_TEX2DARRAY(name,uv) |
Sample from a texture array with a float3 UV; the z component of the coordinate is array element index. |
UNITY_SAMPLE_TEX2DARRAY_LOD(name,uv,lod) |
Sample from a texture array with an explicit mipmap level. |
Индикаторы проходов (pass) для поверхностных шейдеров
Компиляция поверхностных шейдеров (Surface Shader), генерирует большое количество кода различных проходов для вычисления освещения. При компиляции каждого прохода определяется один из следующих макросов:
Macro: | Use: |
---|---|
UNITY_PASS_FORWARDBASE |
* UNITY_PASS_FORWARDBASE - базовый проход для системы освещения forward rendering (главный направленный источник света, лайтмапы, SH). |
UNITY_PASS_FORWARDADD |
* UNITY_PASS_FORWARDADD - аддитивный проход для системы освещения forward rendering (по одному источнику света на каждый проход). |
UNITY_PASS_DEFERRED |
* UNITY_PASS_PREPASSBASE - базовый проход для системы освещения deferred lighting (отрисовка нормалей и спекулярных экспонент). |
UNITY_PASS_SHADOWCASTER |
* UNITY_PASS_SHADOWCASTER - проход для источника тени. |
UNITY_PASS_PREPASSBASE |
* UNITY_PASS_PREPASSBASE - базовый проход для системы освещения deferred lighting (отрисовка нормалей и спекулярных экспонент). |
UNITY_PASS_PREPASSFINAL |
* UNITY_PASS_PREPASSFINAL - конечный проход для системы освещения deferred lighting (применение освещения и текстур). |