Unity 6.3
0 онлайн 25 гостей 3 в системе
Вход

Введение в варианты шейдеров

Варианты шейдера, также иногда называемые пермутациями шейдера, являются одним из способов введения условного поведения в код шейдера.

Unity компилирует исходные файлы шейдеров в шейдерные программы. Каждая скомпилированная шейдерная программа имеет варианты: различные версии программы для различных условий. Во время выполнения, Unity использует вариант, соответствующий текущим требованиям. Вы настраиваете варианты с помощью шейдер ключевые слова.

Для общего обзора условных условий в коде шейдера и когда использовать какие методы, см. Условные условия в коде шейдера. Для получения дополнительной информации о том, как Unity загружает варианты шейдера, см. Загрузка шейдера.

Шейдеры с большим количеством вариантов называются «мега-шейдеры» или «убер-шейдеры». Standard Shader Unity является примером такого шейдера.

Преимущества и недостатки вариантов шейдеров

Основное преимущество вариантов шейдера заключается в том, что они позволяют использовать условные условия выполнения в шейдерных программах, без GPU воздействия на производительность динамического ветвления. Основной недостаток вариантов шейдера заключается в том, что большое количество из них может привести к увеличению времени сборки, высокому использованию памяти шейдера и задержкам компиляции шейдера.

Создавая варианты шейдера, Unity применяет статическое ветвление и формирует несколько небольших специализированных шейдерных программ. Во время выполнения используется та программа, которая соответствует условиям. Благодаря этому код, который при динамическом ветвлении, скорее всего, снизил бы производительность GPU, можно вынести в варианты шейдера без потери производительности.

Однако большое количество вариантов может привести к увеличению времени сборки, размеров файлов, использования памяти выполнения и времени загрузки. Это также приводит к повышению сложности при ручной предварительной загрузке («предварительном нагреве») шейдеров. Когда проект содержит очень большое количество вариантов шейдеров, эти проблемы могут привести к значительным проблемам с производительностью и рабочим процессом.

Предупреждение: Легко случайно создать чрезмерно большое количество вариантов шейдера, что может привести к значительным проблемам производительности. Поэтому очень важно понять как Unity определяет количество вариантов шейдера, как исключить («стрип») ненужных вариантов из компиляции, и когда использовать другие типы условий в шейдерах.

Количество вариантов шейдеров

Во время сборки Unity компилирует один набор вариантов шейдера для каждой графики API для текущей цели сборки. Число вариантов для каждой комбинации графики API и цели сборки зависит от исходных файлов шейдера и использования ключевых слов для шейдера.

Вы можете проверить, сколько вариантов шейдеров у вас есть.

Графика APIs

Unity компилирует один набор вариантов шейдеров для каждой графики API в списке для текущей цели сборки. Шайдеры различаются для каждой комбинации цели сборки и графики API; например, Unity компилирует различные шейдеры для Metal на iOS и для Metal на macOS.

Некоторые программы или ключевые слова для шейдеров могут быть ориентированы только на определенную графику API или определенную цель сборки, поэтому общее количество вариантов для каждой комбинации графики API и цели сборки может отличаться; однако процесс компиляции этих вариантов одинаков.

Для просмотра и редактирования списка графики APIs для текущей цели сборки, используйте Настройки игрока, или в окне PlayerSettings API.

Количество шейдерных программ

Unity должен определить, сколько шейдерных программ компилировать для текущей комбинации цели сборки и графики API.

Для каждого исходного файла шейдера, который включается в вашу сборку, Unity определяет, сколько уникальных программ шейдера она определяет:

  • Ассет вычислительного шейдера определяет одну программу шейдера.
  • В ручном шейдере количество программ шейдера зависит от вашего кода. Общее число программ шейдера включает:
    • Все шейдерные стадии во всех проходах самого исходного файла. Например, каждая вершинная стадия задаёт одну шейдерную программу, каждая фрагментная стадия — ещё одну, и так далее.
    • Все стадии шейдера во всех проходах в зависимости от исходного файла. Это включает в себя все резервные шейдеры, и все пропуска, которые включены с помощью UsePass команда.
  • В шейдере Shader Graph число программ шейдера зависит от кода, который Unity генерирует из вашего графика. Чтобы увидеть код шейдера, который генерирует Unity, контекстно щелкните ассет Shader Graph и выберите Посмотреть генерированный код. Затем вы можете определить общее число программ шейдера так же, как и для шейдера, написанного вручную.

Примечание: Исходный файл шейдера включается в сборку, если на него делается ссылка в сцене в этой сборке, ссылка на него делается чем-то в Ресурсы папки или включены в Всегда включённые шейдеры раздела бюджета Настройки графики окно.

Ключевые слова, влияющие на программу шейдера

Когда Unity определит, сколько шейдерных программ она должна компилировать для текущей цели сборки и графики API, она затем определит, сколько вариантов шейдеров она должна компилировать для каждой шейдерной программы.

Для каждой программы шейдера Unity определяет комбинацию ключевых слов шейдера, которые приводят к различным вариантам. Это включает:

Количество вариантов шейдера, которые Unity компилирует для программы шейдера, является произведением наборов ключевых слов; то есть Unity компилирует один вариант для каждой комбинации, которая включает один элемент из каждого набора.

Например, этот набор содержит три ключевых слова варианта шейдера:

  • COLOR_RED
  • COLOR_GREEN
  • COLOR_BLUE

Этот набор содержит четыре ключевых слова варианта шейдера:

  • QUALITY_LOW
  • QUALITY_MEDIUM
  • QUALITY_HIGH
  • QUALITY_ULTRA

Шейдеровская программа, затронутая этими ключевыми словами варианта шейдера, приведет к следующим двенадцати вариантам:

  • COLOR_RED и QUALITY_LOW
  • COLOR_RED и QUALITY_MEDIUM
  • COLOR_RED и QUALITY_HIGH
  • COLOR_RED и QUALITY_ULTRA
  • COLOR_GREEN и QUALITY_LOW
  • COLOR_GREEN и QUALITY_MEDIUM
  • COLOR_GREEN и QUALITY_HIGH
  • COLOR_GREEN и QUALITY_ULTRA
  • COLOR_BLUE и QUALITY_LOW
  • COLOR_BLUE и QUALITY_MEDIUM
  • COLOR_BLUE и QUALITY_HIGH
  • COLOR_BLUE и QUALITY_ULTRA

Количество вариантов, которые Unity компилирует, может расти очень быстро, по мере того как вы добавляете больше наборов ключевых слов вариантов шейдера. Термином для этого очень быстрого роста является комбинаторный взрыв.

Например, рассмотрим довольно типичный случай использования, когда у шейдера есть несколько наборов ключевых слов вариантов шейдера, каждый из которых содержит два ключевых слова (<feature name>_ON и <feature name>_OFF). Если у шейдера есть два таких набора ключевых слов, это приводит к четырем вариантам. Если у шейдера есть десять таких наборов ключевых слов, это приводит к 1024 вариантам.

Дедупликация вариантов шейдеров

После компиляции, Unity автоматически идентифицирует идентичные варианты в одном и том же Проходе, и обеспечивает, что эти идентичные варианты указывают на один и тот же байткод. Это называется дедупликация.

Дедупликация предотвращает увеличение размера файла идентичными вариантами в одном и том же Проходе; однако, идентичные варианты все равно приводят к потере работы во время компиляции, увеличению использования памяти и времени загрузки шейдеров во время выполнения. Исходя из этого, всегда лучше удалить ненужные варианты.