Связанные текстуры и сэмплеры
Большую часть времени при выборке текстур в шейдерахпрограмме, работающей на графическом процессоре. Подробнее
См. в Словарь, состояние выборки текстуры должно исходить из настройки текстуры — по сути, текстуры и сэмплеры связаны вместе. Это поведение по умолчанию при использовании синтаксиса шейдера в стиле DX9:
sampler2D _MainTex;
// ...
half4 color = tex2D(_MainTex, uv);
Использование ключевых слов sampler2D, sampler3D, samplerCUBE HLSL объявляет как текстуру, так и сэмплер.
В большинстве случаев это именно то, что вам нужно, и это единственный поддерживаемый вариант в старых графических API (OpenGL ES).
Отдельные текстуры и сэмплеры
Многие графические API и графические процессоры позволяют использовать меньше сэмплеров, чем текстур, а синтаксис связанной текстуры и сэмплера может не позволить писать более сложные шейдеры. Например, Direct3D 11 позволяет использовать до 128 текстур в одном шейдере, но только до 16 сэмплеров.
Unity позволяет объявлять текстуры и сэмплеры с использованием синтаксиса HLSL в стиле DX11 со специальным соглашением об именах для их сопоставления: сэмплеры, имена которых имеют форму «sampler»+TextureName, будут брать состояния выборки из этой текстуры.
Фрагмент шейдера из раздела выше можно переписать с использованием синтаксиса HLSL в стиле DX11, и он будет делать то же самое:
Texture2D _MainTex;
SamplerState sampler_MainTex; // "sampler" + “_MainTex”
// ...
half4 color = _MainTex.Sample(sampler_MainTex, uv);
Однако таким образом можно написать шейдер, который будет «повторно использовать» сэмплеры из других текстур, при этом сэмплируя более одной текстуры. В приведенном ниже примере сэмплируются три текстуры, но для всех них используется только один сэмплер:
Texture2D _MainTex;
Texture2D _SecondTex;
Texture2D _ThirdTex;
SamplerState sampler_MainTex; // "sampler" + “_MainTex”
// ...
half4 color = _MainTex.Sample(sampler_MainTex, uv);
color += _SecondTex.Sample(sampler_MainTex, uv);
color += _ThirdTex.Sample(sampler_MainTex, uv);
Обратите внимание, однако, что синтаксис HLSL в стиле DX11 не работает на некоторых старых платформах (например, OpenGL ES 2.0). Подробнее см. в разделе Использование HLSL в Unity. Вы можете указать #pragma target 3.5
(см. цели компиляции шейдера, чтобы не использовать шейдер на старых платформах).
Unity предоставляет несколько макросов шейдеров, помогающих объявлять и сэмплировать текстуры с использованием подхода «отдельных семплеров», см. встроенные макросы. Приведенный выше пример можно было бы переписать таким образом, используя указанные макросы:
UNITY_DECLARE_TEX2D(_MainTex);
UNITY_DECLARE_TEX2D_NOSAMPLER(_SecondTex);
UNITY_DECLARE_TEX2D_NOSAMPLER(_ThirdTex);
// ...
half4 color = UNITY_SAMPLE_TEX2D(_MainTex, uv);
color += UNITY_SAMPLE_TEX2D_SAMPLER(_SecondTex, _MainTex, uv);
color += UNITY_SAMPLE_TEX2D_SAMPLER(_ThirdTex, _MainTex, uv);
Приведенный выше код будет скомпилирован на всех платформах, поддерживаемых Unity, но на более старых платформах, таких как DX9, будет использоваться три сэмплера.
Состояния встроенного сэмплера
В дополнение к распознаванию объектов HLSL SamplerState, названных как «sampler»+TextureName, Unity также распознает некоторые другие шаблоны в именах сэмплеров. Это полезно для объявления простых жестко запрограммированных состояний выборки непосредственно в шейдерах. Пример:
Texture2D _MainTex;
SamplerState my_point_clamp_sampler;
// ...
half4 color = _MainTex.Sample(my_point_clamp_sampler, uv);
Имя «my_point_clamp_sampler» будет распознано как сэмплер, который должен использовать фильтрацию текстуры Point (ближайшей) и режим наложения текстуры Clamp.
Имена семплеров, распознаваемые как «встроенные» состояния семплеров (без учета регистра):
«Точка», «Линейный» или «Трилинейный» (обязательно) задают режим фильтрации текстуры.
-
«Clamp», «Repeat», «Mirror» или «MirrorOnce» (обязательно) задают режим переноса текстуры.
- Режимы переноса можно указать для каждой оси (UVW), например. «ClampU_RepeatV».
«Сравнить» (необязательно) — настроить сэмплер для сравнения глубины; использовать с типом HLSL SamplerComparisonState и функциями SampleCmp/SampleCmpLevelZero.
"AnisoX" (где X может быть 2/4/8 или 16, например,
Ansio8
) можно добавить для запроса анизотропной фильтрации. Вот пример выборки текстуры с помощьюsampler_linear_repeat
иsampler_point_repeat
SamplerStates соответственно, иллюстрирующий, как имя управляет режимом фильтрации:
Вот пример с SmpClampPoint
, SmpRepeatPoint
, SmpMirrorPoint
, SmpMirrorOncePoint
, Smp_ClampU_RepeatV_Point
SamplerStates соответственно, показывая, как имя управляет режимом переноса. В последнем примере для горизонтальной (U) и вертикальной (V) осей установлены разные режимы переноса. Во всех случаях координаты текстуры изменяются от –2,0 до +2,0.
Так же, как синтаксис отдельной текстуры и сэмплера, встроенные состояния сэмплера не поддерживаются на некоторых платформах. В настоящее время они реализованы на Direct3D 11/12, PS4, XboxOne и Metal.
Обратите внимание, что режим наложения текстур «MirrorOnce» не поддерживается на большинстве мобильных графических процессоров/API и будет переключаться на режим «Зеркало», когда поддержки нет.
Новая функция в 2017.1