Hero background image
Animate with Unity
Оптимизация производительности для высококлассной графики на ПК и консолях

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

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

ИЛЛЮСТРАЦИЯ ТОГО, КАК РАБОТАЕТ ПРЯМОЙ РЕНДЕРИНГ
ИЛЛЮСТРАЦИЯ ТОГО, КАК РАБОТАЕТ ПРЯМОЙ РЕНДЕРИНГ
Передняя визуализация

При выборе конвейера рендеринга учитывайте эти соображения. Наряду с выбором конвейера вам нужно будет выбрать путь рендеринга.

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

Путь рендеринга вперед

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

Конвейер передает каждый объект по одному в графический API. Перспективный рендеринг требует затрат на каждый свет, поэтому чем больше света в вашей сцене, тем больше времени займет рендеринг.

Рендерер Forward во встроенном конвейере рисует каждый свет в отдельном проходе для каждого объекта. Если на один и тот же объект GameObject попадает несколько источников света, это может привести к значительной перерисовке, когда перекрывающиеся области должны отрисовывать один и тот же пиксель более одного раза. Чтобы уменьшить перегрузку, минимизируйте количество ламп реального времени.

Вместо того чтобы выполнять один проход для каждого света, URP собирает свет для каждого объекта. Это позволяет вычислять освещение за один проход, что приводит к меньшему количеству вызовов рисования по сравнению с Forward Renderer во встроенном конвейере рендеринга.

ИЛЛЮСТРАЦИЯ ТОГО, КАК РАБОТАЕТ ПУТЬ РЕНДЕРИНГА С ОТЛОЖЕННЫМ ЗАТЕНЕНИЕМ
ИЛЛЮСТРАЦИЯ ТОГО, КАК РАБОТАЕТ ПУТЬ РЕНДЕРИНГА С ОТЛОЖЕННЫМ ЗАТЕНЕНИЕМ
Отложенное оказание услуг

Встроенный конвейер рендеринга, URP и конвейер рендеринга высокой четкости (HDRP) также используют путь рендеринга Deferred Shading. В режиме Deferred Shading освещение не рассчитывается для каждого объекта.

Вместо этого Deferred Shading откладывает тяжелый рендеринг, например освещение, на более поздний этап и использует два прохода. В первом проходе, который также называется G-буфер геометрии, Unity рендерит объекты GameObjects. Эта передача извлекает несколько типов геометрических свойств и сохраняет их в наборе текстур.

Текстуры G-буфера могут включать в себя:

- Диффузный и зеркальный цвета

- Гладкость поверхности

- Окклюзия

- Нормали мирового пространства

- Излучение + окружающая среда + отражения + лайтмапы

Во время второго прохода, или прохода освещения, Unity рендерит освещение сцены на основе G-буфера. Представьте себе итерацию по каждому пикселю и вычисление информации об освещении на основе буфера, а не отдельных объектов. Добавление дополнительных источников света, не отбрасывающих тени, в режиме Deferred Shading не приводит к такому снижению производительности, как при рендеринге Forward.

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

ОСНОВАННЫЙ НА УЗЛАХ ВИЗУАЛЬНЫЙ ИНТЕРФЕЙС ДЛЯ ПОСТРОЕНИЯ ШЕЙДЕРОВ В ШЕЙДЕРНОМ ГРАФЕ
ОСНОВАННЫЙ НА УЗЛАХ ВИЗУАЛЬНЫЙ ИНТЕРФЕЙС ДЛЯ ПОСТРОЕНИЯ ШЕЙДЕРОВ В ШЕЙДЕРНОМ ГРАФЕ
Графики шейдеров

И HDRP, и URP поддерживают Shader Graph- визуальный интерфейс для создания шейдеров на основе узлов. Он позволяет пользователям, не имеющим опыта программирования шейдеров, создавать сложные эффекты затенения.

В настоящее время в Shader Graph доступно более 150 узлов. Кроме того, вы можете создавать свои собственные узлы с помощью API.

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

Затем шейдерный график передается в бэкэнд конвейера рендеринга. В итоге получается шейдер ShaderLab, функционально схожий с шейдером, написанным на HLSL или Cg.

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

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

Если вы работаете на GPU, следуйте этим рекомендациям по повышению производительности с помощью Shader Graph:

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

По возможности используйте меньший формат данных: Рассмотрите возможность использования Vector2 вместо Vector3 или уменьшения точности (например, половина вместо float), если ваш проект позволяет это сделать.

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

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

Оптимизируйте вручную: Даже опытные графические программисты могут использовать Shader Graph, чтобы набросать шаблонный код для шейдера, основанного на сценарии. Выберите актив Shader Graph, затем в контекстном меню выберите Copy Shader. Создайте новый HLSL/Cg-шейдер, а затем вставьте в него скопированный Shader Graph. Это односторонняя операция, но она позволяет выжать дополнительную производительность с помощью ручных оптимизаций.

ВСЕГДА ВКЛЮЧЕННЫЙ СПИСОК ШЕЙДЕРОВ В НАСТРОЙКАХ ГРАФИКИ
ВСЕГДА ВКЛЮЧЕННЫЙ СПИСОК ШЕЙДЕРОВ В НАСТРОЙКАХ ГРАФИКИ
Удалите настройки встроенных шейдеров

Удалите все неиспользуемые шейдеры из списка Always Included Shaders, который находится в настройках графики(Edit > Project Settings > Graphics). Добавьте сюда все шейдеры, которые необходимы для работы приложения.

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

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

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

Сначала разберите файл Editor.log на предмет синхронизации и размера шейдеров. Затем найдите строки, начинающиеся с Compiled shader и Compressed shader.

В этом примере журнала показана следующая статистика:

Скомпилируйте шейдер 'TEST Standard (Specular setup)' за 31,23 с
d3d9 (всего внутренних программ: 482, уникальный: 474)
d3d11 (всего внутренних программ: 482, уникальный: 466)
металл (всего внутренних программ: 482, уникальный: 480)
glcore (всего внутренних программ: 482, уникальный: 454)
Сжатие шейдера 'TEST Standard (Specular setup)' на d3d9 с 1,04 МБ до 0,14 МБ
Сжатие шейдера 'TEST Standard (Specular setup)' на d3d11 с 1,39 МБ до 0,12 МБ
Сжатие шейдера 'TEST Standard (Specular setup)' на металле с 2,56 МБ до 0,20 МБ
Сжатие шейдера 'TEST Standard (Specular setup)' на glcore с 2,04 МБ до 0,15 МБ

Эти данные рассказывают о шейдере несколько вещей:

- Из-за #pragma multi_compile и shader_feature он расширяется до 482 вариантов.

- Unity сжимает шейдер, включенный в данные игры, примерно до суммы сжатых размеров: 0,14+0,12+0,20+0,15 = 0,61 МБ.

- Во время выполнения Unity хранит сжатые данные в памяти (0,61 МБ), в то время как данные для используемого в данный момент графического API остаются несжатыми. Например, если ваш текущий API - это Metal, то его размер составит 2,56 МБ.

После завершения сборки Project Auditor (экспериментальный) может проанализировать журнал Editor.log, чтобы вывести список всех шейдеров, ключевых слов шейдеров и вариантов шейдеров, скомпилированных в проект. Он также может анализировать Player.log после запуска игры. Это показывает, какие варианты приложения были скомпилированы и использованы во время выполнения.

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

Прочитайте статью Stripping scriptable shader variants, чтобы увидеть этот процесс в деталях.

СГЛАЖИВАНИЕ КАК ЭФФЕКТ ПОСТОБРАБОТКИ НА HDRP-КАМЕРЕ
СГЛАЖИВАНИЕ КАК ЭФФЕКТ ПОСТОБРАБОТКИ НА HDRP-КАМЕРЕ
Сглаживание краев с помощью сглаживания

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

Если вы используете рендеринг вперед с помощью встроенного конвейера рендеринга, многовыборочное сглаживание (MSAA) доступно в параметре Качество в настройках качества. MSAA обеспечивает высококачественное сглаживание, но может быть дорогостоящим. Параметр MSAA Sample Count из выпадающего меню определяет, сколько образцов рендерер использует для оценки эффекта(None, 2X, 4X, 8X). Если вы используете Forward rendering с URP или HDRP, вы можете включить MSAA на актив URP или HDRP Asset соответственно.

Также можно добавить сглаживание в качестве эффекта постобработки. Он появляется в компоненте Camera (в разделе Anti-aliasing) с парой опций:

- Быстрое приближенное сглаживание (FXAA) сглаживает края на уровне отдельных пикселей. Это наименее ресурсоемкий тип сглаживания. Это немного размывает конечное изображение.

- Субпиксельное морфологическое сглаживание (SMAA) смешивает пиксели по границам изображения. Он обеспечивает гораздо более четкие результаты, чем FXAA, и подходит для плоских, мультяшных или чистых художественных стилей.

В HDRP вы также можете использовать FXAA и SMAA в постобработке сглаживания на камере с дополнительной опцией:

- Темпоральное сглаживание (TAA) сглаживает края, используя кадры из буфера истории. Это работает эффективнее, чем FXAA, но для его работы необходимы векторы движения. TAA также может улучшить Ambient Occlusion и объемность. В целом он более качественный, чем FXAA, но требует дополнительных ресурсов и может иногда давать артефакты призрачности.

ОТРЕГУЛИРУЙТЕ НАСТРОЙКИ LIGHTMAPPING (WINDOWS > RENDERING > LIGHTING SETTINGS) И РАЗМЕР LIGHTMAP, ЧТОБЫ ОГРАНИЧИТЬ ИСПОЛЬЗОВАНИЕ ПАМЯТИ.
ОТРЕГУЛИРУЙТЕ НАСТРОЙКИ LIGHTMAPPING (WINDOWS > RENDERING > LIGHTING SETTINGS) И РАЗМЕР LIGHTMAP, ЧТОБЫ ОГРАНИЧИТЬ ИСПОЛЬЗОВАНИЕ ПАМЯТИ.
Запекание лайтмапов

Самый быстрый вариант создания освещения - тот, который не нужно вычислять на каждый кадр. Используйте Lightmapping, чтобы запечь статичное освещение всего один раз, вместо того чтобы рассчитывать его в реальном времени.

Добавьте эффектное освещение к статичной геометрии с помощью Глобальное освещение (GI). Отметьте опцию Contribute GI для объектов, чтобы сохранить высококачественное освещение в виде лайтмапов.

Процесс создания светомаскировочного окружения занимает больше времени, чем просто размещение света в сцене, но он дает такие преимущества, как:

- Работает в два-три раза быстрее при двухпиксельном освещении

- Улучшенные визуальные эффекты благодаря функции Global Illumination, которая позволяет рассчитать реалистичное прямое и косвенное освещение, а лайтмаппер сглаживает и обесцвечивает полученную карту

- Запеченные тени и освещение визуализируются без снижения производительности, которое обычно возникает при использовании освещения и теней в реальном времени

Более сложные сцены могут потребовать длительного времени запекания. Если ваше оборудование поддерживает Progressive GPU Lightmapper (в предварительном просмотре), эта опция может значительно ускорить генерацию лайтмапов за счет использования GPU вместо CPU.

Следуйте этому руководству, чтобы начать работу с Lightmapping в Unity.

КАЖДЫЙ ОТРАЖАЮЩИЙ ЗОНД ПОЛУЧАЕТ ИЗОБРАЖЕНИЕ ОКРУЖАЮЩЕЙ СРЕДЫ В ВИДЕ ТЕКСТУРЫ CUBEMAP.
КАЖДЫЙ ОТРАЖАЮЩИЙ ЗОНД ПОЛУЧАЕТ ИЗОБРАЖЕНИЕ ОКРУЖАЮЩЕЙ СРЕДЫ В ВИДЕ ТЕКСТУРЫ CUBEMAP.
Минимизация отражения зондов

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

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

- Используйте Тип: Запеченный, чтобы избежать покадрового обновления.

- Если использование Type: В режиме реального времени необходим в URP, старайтесь избегать Every Frame, когда это возможно. Настройте Режим обновления и Временная нарезка чтобы уменьшить частоту обновления. Вы также можете управлять обновлением с помощью опции Via Scripting и выводить зонд из пользовательского сценария.

- Если использование Type: В режиме реального времени необходим в HDRP, выберите режим " По требованию ". Вы также можете изменить настройки кадра в разделе Настройки проекта > Настройки HDRP по умолчанию.

- Уменьшите качество и функции в разделе " Отражение в реальном времени" для повышения производительности.

ОТКЛЮЧИТЕ ОТБРАСЫВАНИЕ ТЕНЕЙ, ЧТОБЫ УМЕНЬШИТЬ КОЛИЧЕСТВО ВЫЗОВОВ РИСОВАНИЯ.
ОТКЛЮЧИТЕ ОТБРАСЫВАНИЕ ТЕНЕЙ, ЧТОБЫ УМЕНЬШИТЬ КОЛИЧЕСТВО ВЫЗОВОВ РИСОВАНИЯ.
Отключить тени

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

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

Замените эффект шейдера

В некоторых случаях можно применить простые приемы, а не добавлять несколько дополнительных ламп. Например, вместо того чтобы создавать свет, который светит прямо в камеру, чтобы создать эффект ободкового освещения, используйте шейдер для имитации ободкового освещения (см. примеры шейдеров Surface Shader для реализации этого в HLSL).

СЛОИ МОГУТ ОГРАНИЧИТЬ ВЛИЯНИЕ СВЕТА ОПРЕДЕЛЕННОЙ МАСКОЙ ОБТРАВКИ.
СЛОИ МОГУТ ОГРАНИЧИТЬ ВЛИЯНИЕ СВЕТА ОПРЕДЕЛЕННОЙ МАСКОЙ ОБТРАВКИ.
Используйте светлые слои

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

СВЕТОВЫЕ ЗОНДЫ ОСВЕЩАЮТ ДИНАМИЧЕСКИЕ ОБЪЕКТЫ НА ЗАДНЕМ ПЛАНЕ.
СВЕТОВЫЕ ЗОНДЫ ОСВЕЩАЮТ ДИНАМИЧЕСКИЕ ОБЪЕКТЫ НА ЗАДНЕМ ПЛАНЕ.
Используйте зонды освещения

Световые зонды хранят информацию о пустом пространстве сцены, обеспечивая высококачественное освещение (как прямое, так и косвенное). Они используют сферические гармоники, которые быстро вычисляются по сравнению с динамическим освещением. Это особенно полезно для движущихся объектов, которые обычно не могут получить запеченный Lightmapping.

Световые зонды могут применяться и к статичным сеткам. В компоненте Mesh Renderer найдите выпадающее меню Receive Global Illumination и переключите его с Lightmaps на Light Probes.

Продолжайте использовать Lightmapping для геометрии большого уровня, но переключитесь на Light Probes для освещения мелких деталей. Освещение Light Probe не требует соответствующих UV, что избавляет вас от необходимости разворачивать сетку. Зонды также занимают меньше места на диске, поскольку не генерируют текстуры Lightmap.

Дополнительную информацию см. в статье Статическое освещение с помощью световых зондов, а также в статье Создание правдоподобных визуальных эффектов в Unity.

Получите бесплатную электронную книгу

Одно из самых полных наших руководств, в котором собрано более 80 действенных советов по оптимизации игр для ПК и консолей. Эти подробные советы, созданные нашими экспертами в области Success и Accelerate Solutions, помогут вам получить максимальную отдачу от Unity и повысить производительность вашей игры.

Понравился ли вам этот контент?