Варианты шейдера, также иногда называемые перестановками шейдера, являются одним из способов введения условного поведения в код шейдера.
Unity компилирует шейдерпрограмму, которая работает на графическом процессоре. Подробнее
Просмотрите в Словарь исходные файлы шейдерных программ. Каждая скомпилированная шейдерная программа имеет один или несколько вариантов: разные версии шейдерной программы для разных условий. Во время выполнения Unity использует вариант, соответствующий текущим требованиям. Вы настраиваете варианты, используя ключевые слова шейдера.
Общие сведения об условных операторах в коде шейдера и о том, когда какой метод использовать, см. в разделе Условные операторы в коде шейдера. Дополнительную информацию о том, как Unity загружает варианты шейдеров, см. в разделе загрузка шейдеров.
Шейдеры с большим количеством вариантов называются "мегашейдерами" или "сверхшейдерами". Примером такого шейдера является стандартный шейдер Unity.
Преимущества и недостатки вариантов шейдера
Основное преимущество вариантов шейдеров заключается в том, что они позволяют использовать условные выражения во время выполнения в ваших шейдерных программах без влияния динамического ветвления на производительность графического процессора. Основной недостаток вариантов шейдеров заключается в том, что их большое количество может привести к проблемам с производительностью как во время сборки, так и во время выполнения.
Когда Unity создает варианты шейдеров, она использует статическое ветвление для создания нескольких небольших специализированных программ шейдеров. Во время выполнения Unity использует программу шейдера, соответствующую условиям. Это означает, что вы можете использовать варианты шейдеров для кода, который может привести к снижению производительности графического процессора в динамической ветви без потери производительности графического процессора.
Однако большое количество вариантов может привести к увеличению времени сборки, размера файлов, использования оперативной памяти и времени загрузки. Это также приводит к большей сложности при ручной предварительной загрузке («предварительном прогреве») шейдеров. Когда проект содержит очень большое количество вариантов шейдеров, эти проблемы могут привести к серьезным проблемам с производительностью и рабочим процессом.
Предупреждение. Легко непреднамеренно создать слишком большое количество вариантов шейдера, что может привести к серьезным проблемам с производительностью. Поэтому очень важно понимать, как Unity определяет количество вариантов шейдера, как исключить (“ strip») ненужные варианты из компиляции и когда использовать другие типы условий в шейдерах.
Количество вариантов шейдера
Во время сборки Unity компилирует один набор вариантов шейдера для каждого графического API для текущей цели сборки. Количество вариантов для каждой комбинации графического API и цели сборки зависит от ваших исходных файлов шейдера и использования вами ключевых слов шейдера.
Графические API
Unity компилирует один набор вариантов шейдера для каждого графического API в списке для текущей цели сборки. Шейдеры различаются для каждой комбинации цели сборки и графического API; например, Unity компилирует различные шейдеры для Metal на iOSмобильной операционной системе Apple. Подробнее
См. в Словарь, чем Metal на macOS.
Некоторые шейдерные программы или ключевые слова могут быть нацелены только на определенный графический API или заданную цель сборки, поэтому общее количество вариантов для каждой комбинации графического API и цели сборки может различаться; однако процесс компиляции этих вариантов одинаков.
Чтобы просмотреть и изменить список графических API для текущей цели сборки, используйте Настройки проигрывателяНастройки, которые позволяют вам установить различные параметры для конкретного игрока для окончательной игры, созданной Unity. Подробнее
См. в окне Словарь или в PlayerSettings API.
Количество шейдерных программ
Unity должна определить, сколько шейдерных программ нужно скомпилировать для текущей комбинации цели сборки и графического API.
Для каждого исходного файла шейдера, включенного в вашу сборку, Unity определяет, сколько уникальных программ шейдера он определяет:
- Ресурс вычислительного шейдера определяет одну программу шейдера.
- В написанном вручную шейдере количество программ шейдера зависит от вашего кода. Итого включает:
- Все этапы шейдера во всех проходах в самом исходном файле. Например, каждый этап вершины определяет одну шейдерную программу; каждый этап фрагмента определяет одну шейдерную программу; и так далее.
- Все этапы шейдера во всех проходах в зависимостях
См. в Словаре исходного файла. Сюда входят все откатные шейдеры и все проходы, включенные с помощью команды UsePass.
- В шейдере Shader Graph количество шейдерных программ зависит от кода, который Unity генерирует из вашего графа. Чтобы просмотреть код шейдера, созданный Unity, щелкните в контексте ресурса Shader Graph и выберите Просмотреть сгенерированный код. Затем вы можете определить общее количество программ шейдеров так же, как и для шейдера, написанного вручную.
Примечание. Исходный файл шейдера включается в сборку, если на него есть ссылка в сценеСцена содержит окружение и меню вашей игры. Думайте о каждом уникальном файле сцены как об уникальном уровне. В каждой сцене вы размещаете свое окружение, препятствия и декорации, по сути проектируя и создавая свою игру по частям. Подробнее
См. в Словарь в этой сборке, на который есть ссылка в Ресурсах или в разделе Всегда включенные шейдеры окна Настройки графики.
Ключевые слова, влияющие на шейдерную программу
Когда Unity определила, сколько шейдерных программ необходимо скомпилировать для текущей цели сборки и графического API, она затем определяет, сколько вариантов шейдеров нужно скомпилировать для каждой шейдерной программы.
Для каждой шейдерной программы Unity определяет комбинацию ключевых слов шейдера, которые приводят к различным вариантам. Это включает:
- Наборы ключевых слов варианта шейдера, объявленные в исходном файле для этого шейдера. Дополнительную информацию см. в разделе Объявление ключевых слов шейдера.
- Наборы ключевых слов шейдера, которые Unity добавляет автоматически. Дополнительную информацию см. в разделе предопределенные ключевые слова для шейдеров Unity.
Количество вариантов шейдеров, которые Unity компилирует для шейдерной программы, является произведением наборов ключевых слов; то есть Unity компилирует один вариант для каждой комбинации, включающей один элемент из каждого набора.
Например, этот набор содержит три ключевых слова варианта шейдера:
- COLOR_RED
- COLOR_GREEN
- COLOR_BLUE
Этот набор содержит четыре ключевых слова варианта шейдера:
- QUALITY_LOW
- QUALITY_MEDIUM
- QUALITY_HIGH
- QUALITY_ULTRA
Шейдерная программа, затронутая этими ключевыми словами варианта шейдера, приведет к следующим двенадцати вариантам:
- COLOR_RED and QUALITY_LOW
- COLOR_RED and QUALITY_MEDIUM
- COLOR_RED and QUALITY_HIGH
- COLOR_RED and QUALITY_ULTRA
- COLOR_GREEN and QUALITY_LOW
- COLOR_GREEN and QUALITY_MEDIUM
- COLOR_GREEN and QUALITY_HIGH
- COLOR_GREEN and QUALITY_ULTRA
- COLOR_BLUE and QUALITY_LOW
- COLOR_BLUE and QUALITY_MEDIUM
- COLOR_BLUE and QUALITY_HIGH
- COLOR_BLUE and QUALITY_ULTRA
Количество вариантов, компилируемых Unity, может очень быстро расти по мере добавления дополнительных наборов ключевых слов вариантов шейдера. Этот очень быстрый рост называется комбинаторным взрывом.
Например, рассмотрим довольно типичный случай использования, когда шейдер имеет ряд наборов ключевых слов вариантов шейдера, каждый из которых содержит два ключевых слова (
и <название функции>_OFF
). Если в шейдере есть два таких набора ключевых слов, получается четыре варианта. Если в шейдере есть десять таких наборов ключевых слов, получается 1024 варианта.
Дедупликация вариантов шейдера
После компиляции Unity автоматически идентифицирует идентичные варианты в одном проходе и гарантирует, что эти идентичные варианты указывают на один и тот же байт-код. Это называется дедупликацией.
Дедупликация не позволяет идентичным вариантам в одном проходе увеличивать размер файла; однако идентичные варианты по-прежнему приводят к напрасной работе во время компиляции и увеличению использования памяти и времени загрузки шейдера во время выполнения. Имея это в виду, всегда лучше удалить ненужные варианты.