**Render State — это набор настроек GPU-пайплайна (графического конвейера), которые определяют **как** отрисовывается примитив, тогда как сам шейдер определяет **чем** он отрисовывается. Unity рассматривает эти настройки как часть «Pipeline State Object», поэтому каждый раз, когда любой из параметров меняется, движок вынужден выполнить `SetPass` и настроить пайплайн заново. ### Ключевые группы настроек render state |Категория|Примеры свойств в Unity|Что управляет на GPU|Почему меняется SetPass| |---|---|---|---| |**Depth / Stencil**|`ZWrite`, `ZTest`, `Stencil { … }`|Буфер глубины и трафарет|Включение/выключение записи глубины или другие правила требуют нового PSO| |**Blending (смешивание)**|`Blend SrcAlpha OneMinusSrcAlpha`, `AlphaToMask`|Режимы смешивания с цветовым буфером|Каждый уникальный набор факторов смешивания = новый пайплайн| |**Rasterization**|`Cull Off/Front/Back`, `Wireframe`, `Offset`|Отсечение граней, полигональный режим|Другие комбинации куллинга → новая конфигурация растеризатора| |**Render Target & Color Mask**|`ColorMask RGB`, MRT-настройки|В какие текстуры и каналы пишем|Изменение списка/маски целей рендеринга требует переподготовки| |**Multisample / Antialiasing**|MSAA Sample Count, `AlphaToMask On`|Кол-во сэмплов, порядок resolve|Разные настройки MSAA несовместимы в одном PSO| |**Dynamic States**(меняют реже)|`Viewport`, `Scissor`, `LineWidth`|Задают через _draw-time_ команды|Влияют меньше: можно менять без нового PSO, но Unity часто фиксирует их вместе| > **Важно:** числовые uniform-свойства (`float`, `vector`, `texture`) _не_ относятся к render state. Их меняют через `MaterialPropertyBlock`, и SRP Batcher подменит буфер параметров без `SetPass`. ### Как это выражается в Unity 1. **Pass / SubShader** Внутри `.shader` каждый `Pass` фиксирует свой набор render-state директив (`Blend`, `Cull`, …). Если два материала используют **один и тот же** pass (вариант), но отличаются только значениями uniform’ов, SRP Batcher оставит их в одном SetPass. 2. **Shader Keywords (shader_feature / multi_compile)** Ключевик, который включает, например, `ZWrite Off` или `Blend Premultiply`, породит новый **shader variant**, а вместе с ним — уникальный render state. Поэтому Unity разорвёт батч и выполнит ещё один `SetPass`. 3. **Graphics Pipeline (URP/HDRP, Built-in)** - В URP/HDRP Unity создаёт _RenderPass/RenderGraph_; для каждого PSO с уникальным (shader variant + render state) формируется собственный индекс в _SRP Batcher Cache_. - В Built-in рендерере правила те же, просто без RenderGraph-абстракции. ### Практический итог для оптимизации - Стремитесь иметь как можно меньше разных комбинаций **Blend / Depth / Cull / Stencil** между объектами, видимыми в одном кадре. - Включайте флаги (`_ALPHATEST_ON`, `_NORMALMAP` …) только тем материалам, которым это действительно нужно. - Для числовых параметров используйте `MaterialPropertyBlock` — он изменяет данные в существующем батче без разрыва. - Проверяйте Frame Debugger: колонка **Batch cause** покажет «Objects use different render states» (или «different keywords») — именно эти отличия вызывают лишние SetPass Calls. Таким образом, **render state** — это «паспорт» конфигурации GPU. Каждый раз, когда этот паспорт отличается, Unity обязана сделать новую команду `SetPass`, что увеличивает нагрузку на CPU и может разбивать SRP-Batcher-батчи, поэтому унификация render state критична для производительности.