[Unity Doc -> Introduction to shader variants](https://docs.unity3d.com/6000.1/Documentation/Manual/shader-variants.html?utm_source=chatgpt.com)
[Unity Doc -> Shader variants and keywords](https://docs.unity3d.com/2020.1/Documentation/Manual/SL-MultipleProgramVariants.html?utm_source=chatgpt.com)
**Определения**
- **Шейдер (shader)** — это одна HLSL-(или GLSL-)программа, описанная в `.shader` или `.hlsl` файле. Она может содержать несколько **SubShader**-ов и **Pass**-ов, но логически считается «одним» шейдером.
- **Вариант шейдера (shader variant)** — это конкретная, скомпилированная под GPU копия того же шейдера, в которой зафиксирована определённая комбинация [[Shader Keywords|shader keywords]]. Каждая комбинация ключевых слов ⇒ отдельный исполняемый бинарь.
---
### Практический пример
```hlsl
// URP Sample
#pragma multi_compile _ // базовый
#pragma multi_compile _NORMALMAP
#pragma shader_feature _ALPHATEST_ON
float4 frag (v2f i) : SV_Target
{
#ifdef _ALPHATEST_ON
clip(i.alpha - _Cutoff);
#endif
float3 n = i.normal;
#ifdef _NORMALMAP
n = SampleNormal(i.uv);
#endif
return float4(Shade(n), 1);
}
```
_Ключи_ → варианты:
| # | Ключи | Назначение |
| --- | ---------------------------- | -------------------- |
| 1 | (ничего) | простая диффузия |
| 2 | `_NORMALMAP` | с нормал-картой |
| 3 | `_ALPHATEST_ON` | с отсечкой (обрезка) |
| 4 | `_NORMALMAP + _ALPHATEST_ON` | обе функции |
Если один материал включает оба ключа, а второй — ни одного, то в кадре будет минимум **2 SetPass**.
---
### Рекомендации по управлению вариантами
1. **Используйте `shader_feature`, а не `multi_compile`,** когда ключ _может_ отсутствовать — Unity отсекает неиспользуемые варианты.
2. **Стриппинг** → _Project Settings → Graphics → Shader Stripping_ + собственные `IShaderVariantFilter`-скрипты, чтобы удалять невозможные комбинации.
3. **Shader Variant Collections (SVC)** и **PreloadShaders** для прогрева (warming) критичных вариантов в загрузочном экране, чтобы не фризить во время игры.
4. **Shared материалы**: убедитесь, что одинаковым объектам назначен _один и тот же_ `.mat`-файл и одинаковый набор ключей, иначе SetPass не сократится.
5. **Каталог ключей ≤ 256**; превышение лимита выводит предупреждение и заставляет Unity перебрать варианты вручную, что бьёт по VRAM.
### Использование разных текстур - это причина создания уникальных shader variant?
**Короткий ответ:** Нет. Замена _MainTex и любых других текстур не порождает новый shader variant. Variant-ы генерируются _исключительно_ комбинацией ключевых слов (shader keywords), которые компилятор видит в `#pragma multi_compile / shader_feature` и параметрами Pass (Blend, ZWrite и т.п.). Текстуры, цвета и числовые свойства — это лишь данные, подставляемые уже в скомпилированный код. ([Unity](https://docs.unity3d.com/2020.1/Documentation/Manual/SL-MultipleProgramVariants.html?utm_source=chatgpt.com "Shader variants and keywords - Unity - Manual"))
### разные значения шейдерных свойств приводит к созданию различных shader variant?
**Короткий ответ — нет.**
Изменение _числовых_ или _текстурных_ значений в Material-е само по себе **не** порождает новый _shader variant_ (вариант шейдера). Варианты создаются **только** при изменении набора _shader keywords_ (ключевых слов препроцессора), которые Вы объявили директивами `#pragma multi_compile` или `#pragma shader_feature`.