Unity определяет несколько макросов препроцессора при компиляции шейдерных программ.
Целевая платформа
Макро: | Целевая платформа: |
---|---|
SHADER_API_D3D11 |
Direct3D 11 |
SHADER_API_GLCORE |
Desktop OpenGL “core” (GL 3/4) |
SHADER_API_GLES |
OpenGL ES 2.0 |
SHADER_API_GLES3 |
OpenGL ES 3.0/3.1 |
SHADER_API_METAL |
iOSМобильная операционная система Apple. More info See in Словарь/Mac Metal |
SHADER_API_VULKAN |
Vulkan |
SHADER_API_D3D11_9X |
Цель Direct3D 11 «уровень функций 9.x» для универсальной платформы Windowsфункция IAP, которая поддерживает симулятор Microsoft In App Purchase, который позволяет вам проверить потоки покупок IAP на устройствах перед публикацией вашего приложения. More info See in Словарь |
SHADER_API_PS4 |
PlayStation 4. SHADER_API_PSSL также определяется. |
SHADER_API_XBOXONE |
Xbox One |
SHADER_API_MOBILE
определен для всех основных мобильных платформ (GLES, GLES3, METAL).
Кроме того, SHADER_TARGET_GLSL
определяется, когда целевым языком затенения является GLSL (всегда верно для платформ OpenGL/GLES).
Целевая модель шейдера
SHADER_TARGET
определяется как числовое значение, соответствующее ShaderA программа, работающая на графическом процессоре. Подробнее
См. в Словарь целевую модель компиляции (т. е. соответствующую #pragma target
директива). Например, SHADER_TARGET
равно 30
при компиляции в Shader model 3.0. Вы можете использовать его в коде шейдера для выполнения условных проверок. Например:
#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
UNITY_VERSION
содержит числовое значение версии Unity. Например, UNITY_VERSION
равно 501
для Unity 5.0.1. Это можно использовать для сравнения версий, если вам нужно написать шейдеры, использующие различные встроенные функции шейдеров. Например, проверка препроцессора #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
определяются при компиляции каждого этапа шейдера. Обычно они полезны при совместном использовании кода шейдера между пикселяминаименьшими единицами компьютерного изображения. Размер пикселя зависит от разрешения вашего экрана. Пиксельное освещение рассчитывается для каждого пикселя экрана. Подробнее
См. в Словарь Шейдеры и вычислительные шейдеры, чтобы обрабатывать случаи, когда некоторые вещи должны сделать немного по-другому.
Помощники по различиям платформ
Прямое использование макросов этих платформ не рекомендуется, так как они не всегда способствуют обеспечению безопасности вашего кода в будущем. Например, если вы пишете шейдер, который проверяет наличие D3D11, вы можете убедиться, что в будущем проверка будет расширена для включения Vulkan. Вместо этого Unity определяет несколько вспомогательных макросов (в HLSLSupport.cginc
):
Macro: | Use: |
---|---|
UNITY_BRANCH |
Добавьте это перед условными операторами, чтобы сообщить компилятору, что это должно быть скомпилировано в фактическую ветку. Заменяется на [branch] на платформах HLSL. |
UNITY_FLATTEN |
Добавьте это перед условными операторами, чтобы сообщить компилятору, что это должно быть сглажено, чтобы избежать фактической инструкции перехода. Заменяется на [flatten] на платформах HLSL. |
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 отображает изображение на экране. Подробнее Увидеть в Словарь глубину Текстуры. |
UNITY_PROJ_COORD(a) |
Учитывая 4-компонентный вектор, это возвращает координату Текстуры, подходящую для спроецированных чтений Текстуры. На большинстве платформ это возвращает заданное значение напрямую. |
UNITY_NEAR_CLIP_VALUE |
Определяется значением ближней обрезной плоскостиплоскости, которая ограничивает, насколько далеко или близко камера может видеть из своего текущего положения. Диапазон обзора камеры находится между дальней и ближней плоскостями отсечения. См. дальнюю плоскость отсечения и ближнюю плоскость отсечения. Подробнее См. в Словарь. Платформы, подобные Direct3D, используют 0.0, а платформы, подобные OpenGL, используют -1.0. |
UNITY_VPOS_TYPE |
Определяет тип данных, необходимый для ввода положения пикселя (VPOS): float2 в D3D9, float4 в других местах. |
UNITY_CAN_COMPILE_TESSELLATION |
Определяется, когда компилятор шейдера «понимает» синтаксис HLSL шейдера тесселяции (в настоящее время только D3D11). |
UNITY_INITIALIZE_OUTPUT(type,name) |
Инициализирует переменную name данного type нулем. |
UNITY_COMPILER_HLSL , UNITY_COMPILER_HLSL2GLSL , UNITY_COMPILER_CG
|
Указывает, какой компилятор шейдеров используется для компиляции шейдеров. Дополнительные сведения см. в документации по компиляции шейдеров. Используйте это, если вы столкнулись с очень специфичным синтаксисом шейдера, обрабатывающим различия между компиляторами, и хотите написать разный код для каждого компилятора. |
-
UNITY_REVERSED_Z
- определено на платформах с использованием обратного Z-буфера. Сохраненные значения Z находятся в диапазоне 1..0 вместо 0..1.
Макросы отображения теней
Объявление и выборка карт теней могут сильно различаться в зависимости от платформы. В Unity есть несколько макросов, помогающих в этом:
Macro: | Use: |
---|---|
UNITY_DECLARE_SHADOWMAP(tex) |
Объявляет переменную Texture карты теней с именем text. |
UNITY_SAMPLE_SHADOW(tex,uv) |
Образцы текстуры карты теней «tex» с заданной координатой «uv» (компоненты XY — это местоположение текстуры, компонент Z — глубина для сравнения). Возвращает одиночное значение с плавающей запятой с теневым термином в диапазоне 0..1. |
UNITY_SAMPLE_SHADOW_PROJ(tex,uv) |
Подобно приведенному выше, но читается ли проективная карта теней. «uv» — это число с плавающей запятой4, все остальные компоненты делятся на .w для выполнения поиска. |
ПРИМЕЧАНИЕ. Не все видеокарты поддерживают карты теней. Используйте SystemInfo.SupportsRenderTextureFormat для проверки поддержки.
Макросы буфера констант
Direct3D 11 группирует все переменные шейдера в «постоянные буферы». Большинство встроенных переменных Unity уже сгруппированы, но для переменных в ваших собственных шейдерах может быть более оптимальным поместить их в отдельные буферы констант в зависимости от ожидаемой частоты обновлений.
Используйте для этого макросы CBUFFER_START(name)
и CBUFFER_END
:
CBUFFER_START(MyRarelyUpdatedVariables)
float4 _SomeGlobalValue;
CBUFFER_END
Макросы объявления текстуры/сэмплера
Обычно вы должны использовать texture2D
в коде шейдера для объявления пары текстуры и сэмплера. Однако на некоторых платформах (таких как DX11) текстуры и сэмплеры являются отдельными объектами, и максимально возможное количество сэмплеров весьма ограничено. В Unity есть несколько макросов для объявления текстур без сэмплеров и для выборки текстуры с использованием сэмплера из другой текстуры. Используйте это, если вы в конечном итоге столкнетесь с ограничениями сэмплера, и вы знаете, что несколько ваших текстур могут фактически использовать сэмплер (сэмплеры определяют режимы фильтрации и переноса текстуры).
Macro: | Use: |
---|---|
UNITY_DECLARE_TEX2D(name) |
Объявляет пару текстуры и сэмплера. |
UNITY_DECLARE_TEX2D_NOSAMPLER(name) |
Объявляет текстуру без сэмплера. |
UNITY_DECLARE_TEX2DARRAY(name) |
Объявляет переменную Sampler массива текстур. |
UNITY_SAMPLE_TEX2D(name,uv) |
Образец из пары текстуры и сэмплера с использованием заданной координаты текстуры. |
UNITY_SAMPLE_TEX2D_SAMPLER( name,samplername,uv) |
Образец из Текстуры (имя), используя Сэмплер из другой Текстуры (имя образца). |
UNITY_SAMPLE_TEX2DARRAY(name,uv) |
Образец из массива текстур с float3 UV; компонент z координаты является индексом элемента массива. |
UNITY_SAMPLE_TEX2DARRAY_LOD(name,uv,lod) |
Образец из массива текстур с явным уровнем MIP-карты. |
Дополнительную информацию см. в документации по состояниям сэмплера.
Индикаторы прохождения шейдера поверхности
Когда поверхностные шейдерыупрощенный способ написания шейдеров для встроенного -в конвейере рендеринга. Подробнее
См. Словарь скомпилированы, они генерируют много кода для различных переходов к сделать освещение. При компиляции каждого прохода определяется один из следующих макросов:
Macro: | Use: |
---|---|
UNITY_PASS_FORWARDBASE |
Упреждающий рендерингПуть рендеринга, при котором каждый объект визуализируется за один или несколько проходов, в зависимости от освещения, воздействующего на объект. Сами источники света также обрабатываются Forward Rendering по-разному, в зависимости от их настроек и интенсивности. Подробнее См. в Словарь базовый проход (основной направленный свет, карты освещения, SH). |
UNITY_PASS_FORWARDADD |
Проход добавки прямого рендеринга (один источник света за проход). |
UNITY_PASS_DEFERRED |
Deferred shadingПуть рендеринга во встроенном конвейере рендеринга, который не накладывает ограничений на количество источников света, которые могут воздействовать на GameObject. Все источники света оцениваются попиксельно, что означает, что все они корректно взаимодействуют с картами нормалей и так далее. Кроме того, все источники света могут иметь файлы cookie и тени. Подробнее Просмотреть в Словарь (рендерит G-буфер). |
UNITY_PASS_SHADOWCASTER |
Отбрасыватель теней и глубина Отрисовка текстуры проходит. |
UNITY_PASS_PREPASSBASE |
Устаревший базовый проход отложенного освещения (отрисовывает нормали и экспоненту отражения). |
UNITY_PASS_PREPASSFINAL |
Финальный проход устаревшего отложенного освещения (применяется освещение и текстуры). |
Отключить автоматическое обновление
UNITY_SHADER_NO_UPGRADE
позволяет запретить Unity автоматически обновлять или изменять файл шейдера.
Вспомогательные макросы текстуры глубины
В большинстве случаев текстуры глубины используются для рендеринга глубины из камерыкомпонента, который создает изображение определенного точка обзора в вашей сцене. Вывод либо рисуется на экране, либо фиксируется в виде текстуры. Подробнее
См. в Словарь. включаемый файл UnityCG.cginc содержит несколько макросов для решения описанной выше сложности в этом случае:
- UNITY_TRANSFER_DEPTH(o): вычисляет глубину глазкового пространства вершины и выводит ее в формате o (который должен быть числом с плавающей запятой2). Используйте его в вершинной программе при рендеринге в текстуру глубины. На платформах с нативными текстурами глубины этот макрос вообще ничего не делает, потому что значение буфера Z отображается неявно.
- UNITY_OUTPUT_DEPTH(i): возвращает глубину глазного пространства из i (должно быть числом с плавающей запятой2). Используйте его в программе фрагмента при рендеринге в текстуру глубины. На платформах с собственными текстурами глубины этот макрос всегда возвращает ноль, поскольку значение буфера Z отображается неявно.
- COMPUTE_EYEDEPTH(i): вычисляет глубину глазкового пространства вершины и выводит ее в o. Используйте его в вершинной программе, когда не выполняется рендеринг в текстуру глубины.
- DECODE_EYEDEPTH(i)/LinearEyeDepth(i): учитывая значение высокой точности из текстуры глубины i, возвращает соответствующую глубину глазного пространства.
- Linear01Depth(i): учитывая значение высокой точности из текстуры глубины i, возвращает соответствующую линейную глубину в диапазоне от 0 до 1.
Примечание. На DX11/12, PS4, XboxOne и Metal диапазон Z-буфера равен 1–0, и определен UNITY_REVERSED_Z. На других платформах диапазон составляет 0–1.
Например, этот шейдер будет отображать глубину его GameObjectsосновного объекта в сценах Unity, который может представлять персонажей, реквизит , пейзажи, камеры, путевые точки и многое другое. Функциональность GameObject определяется прикрепленными к нему компонентами. Подробнее
См. в Словарь:
Shader "Render Depth" {
SubShader {
Tags { "RenderType"="Opaque" }
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f {
float4 pos : SV_POSITION;
float2 depth : TEXCOORD0;
};
v2f vert (appdata_base v) {
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
UNITY_TRANSFER_DEPTH(o.depth);
return o;
}
half4 frag(v2f i) : SV_Target {
UNITY_OUTPUT_DEPTH(i.depth);
}
ENDCG
}
}
}