Unity 6.3
0 онлайн 72 гостей 3 в системе
Вход
Оптимизация производительности Шаг 7 из 7

Оптимизация пользовательских шейдеров

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

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

Проверить GPU емкость

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

  • Высокая пропускная способность текстуры, что означает, что GPU приближается к предельному количеству гигабайт текстурных данных, которые он может читать и записывать в секунду.
  • Высокая пропускная способность буфера, что означает, что GPU приближается к предельному количеству гигабайт буферных данных, которые он может читать и записывать в секунду.
  • Высокая мощность арифметического логического блока (ALU), что означает, что математический процессор достигает предела количества операций, которые он может выполнять в секунду.

В зависимости от платформы доступ ко всем этим показателям производительности может быть ограничен.

Сокращение чтения и записи текстуры

Чтобы уменьшить количество чтений текстуры, используйте следующие методы:

  • Используйте математику вместо выборки текстур. Например, вычислите градиент или форму вместо считывания текстуры.
  • Чтение упакованной текстуры, которая представляет собой одну текстуру, в которой каждый канал является разной текстурой. Информацию о том, как Universal Render Pipeline (URP) упаковывает текстуры, см. в Назначение упакованной текстуры канала материалу URP.
  • Включить mipmaps.

Чтобы уменьшить количество записей текстуры, используйте следующие методы:

  • Уменьшение количества размеров объекта рендеринга, в который пишет шейдер.
  • Используйте формат для целевого объекта рендеринга, который использует меньше бит на пиксель. Например, используйте 16-битный формат, такой как ARGB16, вместо 32-битного формата, такого как ARGB32, или используйте формат с меньшим количеством каналов. Дополнительные сведения см. в разделе GPU Texture formats reference.
  • Отключите Multisample Anti-aliasing (MSAA) или уменьшите число выборок на пиксель. Дополнительные сведения см. в Добавить сглаживание.
  • Если ваш шейдер записывает на несколько целей рендеринга (MRT), записывайте на упакованную текстуру вместо этого, или избегайте записи на все цели рендеринга, если это не нужно.

Сокращение чтения и записи в буфер

Чтобы уменьшить количество данных, которые GPU считывает из буферов и записывает в них, используйте следующие подходы:

  • Используйте буфер только для чтения, если это возможно. Используйте унифицированный буфер вместо структурированного буфера, например, используйте ComputeBufferType.Constant для вычислительных буферов и GraphicsBuffer.Target.Constant для графических буферов.
  • Чтение значений из буфера в порядке, так что GPU извлекает значения из текущего кэша, а не читает из буфера снова.

Сокращение арифметических операций

Чтобы ограничить количество операций, выполняемых ALU, используйте следующие подходы:

  • Перемещение вычислений из шейдера фрагментов в шейдер вершин, так что ALU вычисляет один раз на вершину, а не один раз на фрагмент. Если вам нужны значения на фрагмент, позвольте GPU интерполировать значения на вершину.

  • Выполните вычисление один раз за кадр в скрипте C#, затем передайте значение в шейдер.

  • Избегайте медленных операций, таких как sqrt, logи exp.

  • Избегайте медленных тригонометрических операций, таких как sin и cos. Используйте dot и cross вместо этого, когда это возможно.

  • Используйте half вместо float. Дополнительные сведения см. в Использование 16-битной точности в шейдерах.

    Примечание: half может вызвать артефакты рендеринга, если вы используете его для позиций в пространстве мира или других переменных, которые должны быть высокой точности.

  • Используйте текстуру поиска (LUT) вместо сложных расчетов, например, для расчета эффектов после обработки, таких как градация цвета.

Отбрасывать больше фрагментов раньше

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

Чтобы проверить, предотвращает ли ваш шейдер раннее отбрасывание фрагментов GPU, проверьте следующие параметры профиля:

  • Низкое число " неудач в тесте Pre-Z ".
  • Небольшая разница между растрованными фрагментами, отправленными в шейдер фрагментов, и количеством раз, когда шейдер фрагментов выполняет их.

Чтобы увеличить количество фрагментов, которые GPU отбрасывает раньше, используйте следующие подходы:

  • Избегайте операций discard и clip в вашем шейдере фрагментов.
  • Если вам нужны discard и clip, например, потому что вы тестируете альфа-канал для альфа-клипинга, используйте свойство conditional или material, чтобы отключить их для GameObjects, которому они не нужны.

Вы также можете создать глубинный препропуск, который записывает глубину объектов перед непрозрачными и прозрачными проходами URP. Дополнительную информацию см. в Запись прохода только глубины в шейдере.

Проверка ветвления

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

Более подробную информацию см. в Как Unity компилирует ветвящиеся шейдеры и Введение в варианты шейдеров.

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