Назад к блогу

Мобильная оптимизация в Unreal Engine: запуск MetaHumans и PCG на 60 FPS

Опубликовано 19 июня 2026 г.
Мобильная оптимизация в Unreal Engine: запуск MetaHumans и PCG на 60 FPS

Коротко о главном

В руководстве рассматриваются методы оптимизации ресурсоемких технологий Unreal Engine, таких как MetaHumans, PCG и материалы Substrate, для достижения стабильных 60 FPS на мобильных устройствах. Описаны настройка лимитов скиннинга костей через DefaultEngine.ini, замена высокозатратного рендеринга strand-волос на оптимизированные hair cards, а также процедура запекания PCG-графов в статические HISM. Дополнительно представлен готовый C++ скрипт для автоматизации применения оптимизаций при спавне персонажей на Android и iOS. В завершение рассматриваются нюансы сетевой оптимизации под мобильные сети и преимущества интеграции готового Multiplayer-Backend на примере платформы horizOn.

Мобильный барьер: перенос Next-Gen графики на мобильные платформы

Ваш красивый PC-проект выдает безупречные 120 FPS на рабочей станции разработчика, но стоит протестировать мобильный билд, как частота кадров падает до однозначных чисел, целевой телефон нагревается, а GPU вылетает из-за переполнения буфера скиннинга. Высокобюджетные фичи вроде MetaHumans, Procedural Content Generation (PCG) и материалов Substrate выглядят потрясающе на PC и консолях, но они известны тем, что буквально ставят мобильные устройства на колени. Мобильные GPU и CPU работают в условиях жестких тепловых и энергетических ограничений, где пропускная способность памяти является дефицитным ресурсом. Адаптация этих Next-Gen возможностей для мобильного релиза — это не просто выбор нужного чекбокса в настройках; она требует глубокого систематического понимания лимитов скиннинга костей, структуры groom, рабочих процессов процедурного запекания и сложности shading материалов.

Проблема скиннинга на GPU и лимита костей

Узкое место скиннинга на GPU на мобильных устройствах

Перед отправкой на GPU skeletal meshes со скиннингом разбиваются на чанки из вершин и костей. Каждый чанк обрабатывается за один draw call, а мобильные GPU имеют строгое аппаратное ограничение на количество матриц костей, для которых они могут одновременно выполнять скиннинг. Это ограничение определяется количеством uniform-векторов, доступных vertex shader. Стандартный скелет персонажа MetaHuman содержит более 600 костей, что легко превышает мобильные лимиты и приводит к ошибкам рендеринга, разрывам вершин (vertex tearing) или полному зависанию GPU.

Чтобы обойти это аппаратное ограничение, необходимо заставить движок разбивать чанки skeletal mesh так, чтобы ни один draw call не ссылался на большее количество костей, чем задано лимитом. Это достигается настройкой параметров совместимости скиннинга. Если не применить эту конфигурацию, модели персонажей будут некорректно обрабатывать скиннинг на устройствах Android и iOS, отображая статичные или сильно искаженные меши.

Настройка DefaultEngine.ini

Чтобы решить проблему с лимитами скиннинга костей, вам необходимо отредактировать конфигурационный файл вашего проекта DefaultEngine.ini. Найдите этот файл в папке Config в корне проекта. В секцию [ConsoleVariables] добавьте следующую строку:

[ConsoleVariables]
Compat.MAX_GPUSKIN_BONES=75

Эта консольная переменная указывает компилятору shader ограничить максимальное количество костей на один чанк скиннинга значением 75. Это строгий аппаратный лимит для устаревших или среднебюджетных мобильных GPU. Имейте в виду, что уменьшение этого значения заставляет компилятор skeletal mesh разбивать меш на большее количество чанков. Хотя это решает проблему совместимости рендеринга, увеличение числа чанков означает больше draw calls, что может перенести узкое место производительности на поток рендеринга CPU (render thread).

Сокращение количества костей и удаление компонентов

Для фоновых персонажей или NPC, которым не требуется детальная мимика лица, следует упростить скелет. Например, удаление костей пальцев рук, ног и мимических костей лица может снизить общее количество костей персонажа с 600+ до менее чем 75. Это позволит рендерить меш персонажа в виде одного чанка без увеличения числа draw calls.

Если вы также развертываете Dedicated Server для своей Multiplayer-игры, клиентская оптимизация — это лишь половина дела. Вам также потребуется оптимизировать серверную производительность, полностью удалив ассеты рендеринга. Ознакомьтесь с нашим пошаговым руководством по теме как настроить asset stripping для Dedicated Server в Unreal Engine, чтобы снизить накладные расходы на память сервера и оптимизировать производительность CPU.

Оптимизация волос MetaHuman: Groom Strands против Hair Cards

Стоимость рендеринга Strand

Технология рендеринга groom strand от Epic динамически отрисовывает отдельные пряди волос. Хотя это позволяет получить высокодетализированные волосы на мощных настольных GPU, такой подход обходится невероятно дорого. Рендеринг strand опирается на проходы compute shader для сортировки по глубине и генерации карт теней (shadow maps), что вызывает существенные накладные расходы на pixel fill rate и пропускную способность памяти.

На мобильных устройствах рендеринг strand либо вообще не поддерживается, либо работает с неприемлемыми затратами — часто на это уходит более 15 мс процессорного времени GPU только на волосы одного персонажа. Мобильным GPU не хватает чистой пропускной способности памяти, необходимой для сортировки и shading сотен тысяч отдельных кривых волос в каждом кадре.

Внедрение Hair Cards

Решением является замена grooms на основе strand на hair cards. Hair cards представляют волосы с помощью плоских упрощенных полигональных мешей с наложенными пре-рендеренными текстурами волос. Такой подход отлично совместим с мобильным forward render path.

Для внедрения hair cards откройте MetaHuman Creator и убедитесь, что вы генерируете LOD для groom на основе карт для вашего персонажа. Замена волос на основе strand на card-based grooms снижает время рендеринга волос одного персонажа примерно с 18,2 мс до 0,9 мс на современном мобильном чипе вроде Apple A15 или Snapdragon 8 Gen 1. Эта огромная экономия позволяет перенаправить бюджет рендеринга на геймплейные элементы или детали окружения.

Отключение Post-Process Anim Blueprints

MetaHumans используют post-process animation blueprints для управления вторичным движением костей, корректирующими формами мышц и динамикой суставов. Хотя на PC это добавляет реалистичное движение кожи, на мобильных устройствах эти сложные скелетные вычисления на CPU выполняются каждый кадр. На мобильных платформах такие накладные расходы на CPU могут легко стать узким местом для game thread.

Вы можете отключить post-process animation blueprint на мобильных устройствах, чтобы высвободить такты CPU. Это делается путем установки значения bDisablePostProcessAnims = true на компонентах skeletal mesh. Отключение этих пост-процессов экономит до 4,5 мс времени кадра на CPU на стандартном мобильном оборудовании.

Оптимизация PCG для мобильных окружений

Накладные расходы на выполнение PCG в рантайме

Фреймворк Procedural Content Generation (PCG) позволяет динамически наполнять окружение, распределяя static meshes, foliage и акторов на основе правил и объемов (volumes). Однако выполнение PCG-графов в рантайме на мобильных CPU вызывает серьезные просадки производительности. Обычная генерация графа в рантайме может заморозить game thread на 1,5–3 секунды во время загрузки уровня или спавна игрока.

В Multiplayer-играх подобные зависания опасны: они могут приводить к потере пакетов и рассинхронизации состояния клиента и сервера. Для поддержания высокой производительности необходимо предварительно запекать PCG-графы в редакторе (pre-bake). Это преобразует процедурные инстансы в статическую геометрию перед сборкой билда игры.

Пошаговый процесс запекания PCG

  1. Выберите PCG Volume: В окне просмотра (viewport) Unreal Editor выберите PCG volume, содержащий элементы вашего окружения.
  2. Сгенерируйте и проверьте: В панели деталей (details panel) объема нажмите Generate, чтобы просмотреть процедурное размещение ваших ассетов.
  3. Экспортируйте в актора: Найдите опцию Export to Actor в меню утилит PCG.
  4. Выберите инстанцированные меши: Выберите Hierarchical Instanced Static Mesh (HISM) в качестве целевого формата. Эта группа инстансов высоко оптимизирована для мобильных GPU, так как отрисовывает все идентичные меши за один GPU draw call.
  5. Очистите граф: После экспорта установите триггер генерации PCG volume в значение Editor Only или очистите объем. Это предотвратит попытки движка воссоздать граф в рантайме.

Динамический куллинг и стриминг HISM

После того как вы запекли PCG-инстансы в HISM, необходимо настроить расстояние их куллинга (отсечения). HISM поддерживают куллинг на уровне отдельных инстансов (per-instance culling), что означает, что инстансы за пределами определенного расстояния от камеры не будут отрисовываться. Задайте значения Start Cull Distance и End Cull Distance в панели деталей компонентов HISM. Для мобильных платформ рекомендуется расстояние куллинга от 5000 до 8000 единиц, чтобы удерживать общее число видимых полигонов в пределах бюджета мобильного GPU.

Скрипт оптимизации на C++ для Production

Чтобы автоматизировать эти оптимизации в рантайме, вы можете написать собственный вспомогательный класс. Следующий код на C++ демонстрирует, как проверить целевую платформу, программно принудительно использовать низкие LOD, отключить post-process animation blueprints и заставить компоненты groom использовать рендеринг на основе карт при спавне MetaHuman на мобильном устройстве. Вы можете реализовать это в классе вроде UMetaHumanMobileOptimizer:

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "Components/SkeletalMeshComponent.h"
#include "GroomComponent.h"
#include "MetaHumanMobileOptimizer.generated.h"

UCLASS()
class MYPROJECT_API UMetaHumanMobileOptimizer : public UBlueprintFunctionLibrary

{
    GENERATED_BODY()

public:
    UFUNCTION(BlueprintCallable, Category = "Optimization")
    static void OptimizeMetaHumanForMobile(AActor* MetaHumanActor)
    {
        if (!MetaHumanActor)
        {
            return;
        }

        // Apply optimizations exclusively on Android and iOS platforms
        #if PLATFORM_ANDROID || PLATFORM_IOS
        TArray<USkeletalMeshComponent*> SkeletalComponents;
        MetaHumanActor->GetComponents<USkeletalMeshComponent>(SkeletalComponents);

        for (USkeletalMeshComponent* MeshComp : SkeletalComponents)
        { 
            if (MeshComp)
            {
                // Force a low LOD (LOD 3 or 4) to bypass dense meshes
                MeshComp->SetMinLOD(3);
                MeshComp->SetForcedLOD(3);

                // Disable expensive post-process animation blueprints
                MeshComp->bDisablePostProcessAnims = true;

                // Adjust animation tick rate to only calculate when visible
                MeshComp->VisibilityBasedAnimTickOption = EVisibilityBasedAnimTickOption::OnlyTickPoseWhenRendered;

                // Strip physics asset to avoid CPU collision overhead on cosmetic joints
                MeshComp->SetPhysicsAsset(nullptr);
            }
        }

        TArray<UGroomComponent*> GroomComponents;
        MetaHumanActor->GetComponents<UGroomComponent>(GroomComponents);

        for (UGroomComponent* GroomComp : GroomComponents)
        {
            if (GroomComp)
            {
                // Force the groom to use card rendering instead of strands
                GroomComp->SetUseCards(true);
            }
        }
        #endif
    }
};

Эту вспомогательную функцию можно вызывать из события BeginPlay вашего персонажа или сразу после спавна актора MetaHuman. За счет использования макросов условной компиляции (PLATFORM_ANDROID || PLATFORM_IOS) компилятор исключит эти переопределения из сборок для PC и консолей, позволяя автоматически сохранять кроссплатформенное качество графики.

Адаптация материалов Substrate для мобильных GPU

Что такое Substrate?

Substrate заменяет традиционную модель шейдинга Unreal Engine на модульный многослойный фреймворк материалов. Substrate позволяет разработчикам наслаивать друг на друга несколько слоев шейдинга (shading slabs) — например, размещать глянцевый слой лака (clear coat) непосредственно поверх шероховатого металла. Хотя Substrate отлично подходит для высококачественного кинематографичного контента, он представляет собой серьезную проблему для производительности мобильных рендереров.

Мобильные GPU сильно полагаются на архитектуру тайлового рендеринга (tiled rendering), где шина памяти между ядром GPU и встроенным буфером кадров (on-chip frame buffer) является основным узким местом. Сложные материалы Substrate увеличивают количество байт на пиксель (BPP), записываемых во фреймбуфер, что вызывает термальный троттлинг и падение частоты кадров.

Управление сложностью материалов с помощью переключателей уровня качества

Чтобы сохранить производительность материалов Substrate на мобильных устройствах, используйте ноды Material Quality Level Switch и Feature Level Switch внутри редактора материалов. Эти ноды позволяют упростить граф материала в зависимости от целевой платформы.

Для мобильных платформ упростите граф, исключив многослойное смешивание Substrate. Вместо этого используйте один слой (slab), который приблизительно воспроизводит визуальный стиль вашего ассета. Направляя ноды материалов через переключатель качества (quality switch), можно снизить требуемую пропускную способность записи с 32 до стандартных 8 байт на пиксель, благодаря чему устройство будет меньше греться, а частота кадров станет стабильной.

5 практических рекомендаций по мобильной оптимизации

  1. Запекайте все PCG-графы в HISMs (pre-bake): Не выполняйте PCG-графы на клиенте в рантайме. Предварительно запекайте графы в Hierarchical Instanced Static Meshes (HISMs) на этапе работы в редакторе и настраивайте соответствующие расстояния начала и конца куллинга.
  2. Глобально ограничьте количество костей: Добавьте Compat.MAX_GPUSKIN_BONES=75 в файл проекта DefaultEngine.ini, чтобы скелетные меши корректно рендерились на мобильных GPU без переполнения буфера.
  3. Используйте исключительно card-based grooms: Отключите grooms на основе strand для мобильных профилей. Рендеринг волос на основе карт сокращает время кадра на GPU с 18 мс до менее чем 1 мс на персонажа.
  4. Используйте переключатели качества материалов (Material Quality Switches): Внедрите ноду Material Quality Level Switch в ваши материалы Substrate, чтобы упростить сложные слои шейдинга до одного слоя (slab) на мобильных платформах, снижая нагрузку на пропускную способность GPU.
  5. Отключайте post-process animation blueprints: Установите bDisablePostProcessAnims = true для компонентов skeletal mesh ваших персонажей на мобильных устройствах, чтобы высвободить ценные такты CPU в game thread.

Формула Multiplayer и Backend

За пределами рендеринга: мобильная оптимизация сети

При разработке кроссплатформенных Multiplayer-игр оптимизация клиента — это лишь часть уравнения. Мобильные устройства часто сталкиваются с нестабильностью сети, переключаясь между мобильным интернетом (5G/4G) и Wi-Fi. Эти колебания вызывают потерю пакетов, джиттер и резкие скачки пинга (latency spikes).

Если ваш код сетевой синхронизации недостаточно надежен, эти скачки задержки могут спровоцировать баг сетевой синхронизации Unreal Engine в Multiplayer, из-за которого репликация акторов рассинхронизируется и ломает состояние игрового мира. Управление состоянием Multiplayer в условиях ограничений мобильных сетей — сложная задача, требующая отказоустойчивых сетевых драйверов, дельта-сжатия (delta compression) и сверки на стороне сервера (server-authoritative reconciliation).

Делегирование инфраструктуры с помощью horizOn

Создание и поддержка отказоустойчивого Backend для Multiplayer своими силами требует огромных инженерных усилий. Вам придется настраивать Load Balancing, управлять глобальной репликацией баз данных, реализовывать логику Matchmaking и обрабатывать мобильные платежи. Разработка такой инфраструктуры может занять месяцы работы и потребует постоянной поддержки.

С horizOn эти сервисы Backend уже преднастроены. horizOn предоставляет разработчикам игр Matchmaking сессий, синхронизацию состояний с низкой задержкой, постоянное хранение данных в БД и кроссплатформенную аутентификацию прямо из коробки. Это позволяет вам сфокусироваться на оптимизации клиентов и доработке геймплейного цикла (game loop) вместо управления серверами и масштабирования баз данных.

Заключение и следующие шаги

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

Готовы масштабировать свой Multiplayer-Backend? Попробуйте horizOn бесплатно или изучите API docs, чтобы узнать, как упростить свою инфраструктуру и синхронизировать игроков между PC, консолями и мобильными платформами.


Источник: Tutorial: Optimizing Next Gen Features for Mobile Game Development