Искать

Советы Asa по профилированию и оптимизации шейдеров

Лучшие советы от Аса Рид: что выбрать — вершинный или фрагментный шейдер, инструменты отладки и семь его самых лучших методов оптимизации.

Вершинный или фрагментный шейдер: что выбрать?

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

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

Unity-shader-optimization-vertex-shader

Пример модели, обработанной вершинным шейдером,из статьи с примерами вершинных и фрагментных шейдеров.

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

Фрагментный шейдер: если вы хотите добиться высокого качества или интересных поверхностных эффектов с мягким, реалистичным освещением, то используйте фрагментный шейдер. Следите за тем, какие именно операции вы добавляете в фрагментные шейдеры, и старайтесь максимально упростить их либо переместить их в вершинный шейдер.

Unity-shader-optimization-vertex-and-fragment-shaders

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

Работая в Unity, обращайте на объявления #pragma или другие случаи использования встроенного функционала Unity в коде вашего шейдера. Вам может показаться, что простая функция вроде изменения альфа-канала не потребует много ресурсов, но если в шейдере есть объявление вроде «#pragma surface surf BlinnPhong», то для расчета освещения по модели Блинна-Фонга шейдер выполнит десятки вычислений. Все операции расчета освещения по этой модели содержатся в файле lighting.cginc, который находится в папке установки Unity. Для более подробной информации смотрите документациюСобственные модели освещения в поверхностных шейдерах.

Профилировка шейдеров

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

Unity-shader-optimization-frame-debugger

Отладчик кадров Unity

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

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

  1. Для iOS и Mac OS: в Xcode есть замечательный встроенный профилировщик кадров, имеющий такие функции, как слепок всей памяти, которую использует GPU для отрисовки нужного кадра; camera.render, который позволяет просмотреть код отрисовки и увидеть иерархию отрисовываемых элементов; вкладка FPS, где показано, как каждый шейдер влияет на общее время рендеринга.

    Unity-shader-optimization-xcode_profiler

    Профилировщик кадров Xcode.

  2. Для PC и Mac есть инструменты RenderDoc и Intel GPA, дающие подробный анализ и поддерживающие широкий спектр устройств.

  3. Занимаясь отладкой программы с целью увеличения производительность или устранения ошибок выполнения для конкретной платформы вроде ARM Mali, PS4, Xbox, Nintendo Switch и т. д., ВСЕГДА пользуйтесь отладчиком кадров от производителя (Frame Debugger) (иногда он называется Frame Profiler или Frame Analyzer). Такие инструменты почти всегда дают наиболее точные данные по аппаратной составляющей и более обширные данные, нежели общие упомянутые выше инструменты.

Семь ключевых методов оптимизации шейдеров

При отрисовке кадров код шейдера обычно выполняет гораздо больше работы, чем игровой код. Попробуйте применить эти методы — они помогут вам оптимизировать производительность и увеличить частоту смены кадров.

  1. Меньше переменных в алгоритмах. Используйте константы или «динамические глобальные переменные» (например, x=4/33, x=4xsin(24)).
  2. Сначала умножайте скалярные величины (float, int), а затем векторные (float3, float4).
  3. Избегайте инструкции discard там, где это возможно, включая альфа-тест (в основном относится к мобильным устройствам). Следите за случаями многократной отрисовки пикселей.
  4. Если возможно, то все вычисления должны выполняться в вершинном шейдере.
  5. Указывайте маску записи для векторной операции, если возможно (если при этом используются не все компоненты результата).
  6. Избегайте ветвления по динамически задаваемым величинам по неглобальным переменным (if-else, циклы).
  7. Проверяйте влияние операций (таких как discard(), floor(), и т. д.) на модель рендерера (OpenGL 2, OpenGL 3, OpenGL ES, и т. д.) и на аппаратное обеспечение.
Дополнительные ресурсы

Документация и обучающие материалы по шейдерам:

Мы очень хотим знать, нравится ли вам наш контент.

Да, хочу больше Нет, могло быть и лучше
Согласен

Мы используем cookie-файлы, чтобы вам было удобнее работать с нашим веб-сайтом. Подробные сведения смотрите на странице политики обработки cookie-файлов.