Unity 6.3
0 онлайн 115 гостей 3 в системе
Вход
Материалы и шейдеры Шаг 262 из 442

Как Unity компилирует ветвящиеся шейдеры

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

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

Динамическое ветвление

Чтобы использовать динамическое ветвление, используйте #pragma dynamic_branch для объявления ключевых слов. Например:

#pragma dynamic_branch RED GREEN

...

if (RED)
{
    // Output red
}
else if (GREEN)
{
    // Output green
}

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

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

Важно: Используйте if с ключевыми словами dynamic_branch, а не директивы препроцессора, такие как #if или #ifdef. Если вы используете #if или #ifdef, команда всегда оценивается как false.

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

Чтобы использовать варианты шейдеров, используйте #pragma multi_compile или #pragma shader_feature для объявления ключевых слов. Например:

#pragma multi_compile RED GREEN

if (RED)
{
    // Output red
}
else if (GREEN)
{
    // Output green
}

Во время компиляции Unity разделяет приведённый выше код на 2 отдельных, но похожих файла шейдеров, называемых вариантами шейдера. Один файл содержит код, выводящий красный цвет, другой — код, выводящий зелёный. При каждом вызове отрисовки Unity отправляет на GPU нужный вариант шейдера.

Во время компиляции каждого варианта шейдера Unity выполняет следующие действия:

  • Устанавливает включённое ключевое слово как 1 в макросе препроцессора. Например, RED становится #define RED 1, так что if (RED) становится if (1).
  • Устанавливает отключенное ключевое слово как 0 в унифицированной целой переменной. Например, GREEN становится static const int GREEN = 0;, так что if (GREEN) становится if (0) и компилятор удаляет ветку.

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

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

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

Если вам нужно использовать скрипт C# для создания ветки шейдера во время выполнения, используйте multi_compile. Unity компилирует варианты шейдера независимо от того, используются ли они материалами в вашей сборке. Например, вы можете использовать multi_compile, чтобы предоставить пользователям динамический контроль над тем, появляется ли туман в игре.

Важная: Если вы используете multi_compile, Unity Например, если у вас есть 8 наборов ключевых слов с 3 ключевыми словами в каждом, то вы можете создать 10 ключевых слов для каждого из них. Unity может компилировать более 6000 вариантов шейдеров. Использование shader_feature вместо этого, или использовать различные способы варианты ленточного шейдера.

Дополнительные ресурсы