Terug naar Blog

Unreal Engine Mobile Optimization: MetaHumans en PCG laten draaien op 60 FPS

Gepubliceerd op 19 juni 2026
Unreal Engine Mobile Optimization: MetaHumans en PCG laten draaien op 60 FPS

Kort samengevat

Deze gids bespreekt hoe je zware Unreal Engine-features zoals MetaHumans, PCG en Substrate-materialen optimaliseert voor mobiele apparaten om een stabiele 60 FPS te behalen. Door bone skinning limits te configureren, strand-based hair te vervangen door hair cards en PCG-graphs vooraf te baken in HISM's, verminder je de GPU- en CPU-belasting aanzienlijk. Tot slot wordt besproken hoe netwerkfluctuaties op mobiel de multiplayer-synchronisatie kunnen verstoren en hoe het backend-platform horizOn helpt bij het oplossen van deze infrastructuuruitdagingen.

The Mobile Barrier: Next-Gen Visuals naar mobiel brengen

Je prachtige PC-project draait op een vlekkeloze 120 FPS op je developer workstation, maar zodra je de mobile package test, stort de frame rate in tot enkele cijfers, loopt de doeltelefoon warm en crasht de GPU door een skinning buffer overflow. High-end features zoals MetaHumans, Procedural Content Generation (PCG) en Substrate-materialen zien er prachtig uit op PC en consoles, maar ze staan erom bekend dat ze mobiele apparaten op de knieën krijgen. Mobiele GPU's en CPU's werken binnen zeer beperkte thermische en stroombudgetten, waarbij memory bandwidth een kostbare bron is. Het aanpassen van deze next-generation features voor mobile deployment is niet zomaar een kwestie van een vinkje aanzetten in de instellingen; het vereist een diepgaand, systematisch begrip van bone skinning limits, groom-structuren, procedural baking workflows en de complexiteit van material shading.

The GPU Skinning and Bone Limit Challenge

De GPU Skinning Bottleneck op mobiel

Skinned skeletal meshes worden opgesplitst in chunks van vertices en bones voordat ze naar de GPU worden gestuurd. Elke chunk wordt verwerkt in een enkele draw call, en mobiele GPU's hebben een strikte hardware-limiet voor het aantal bone matrices dat ze tegelijkertijd kunnen skinnen. Deze beperking wordt bepaald door het aantal uniform vectors dat beschikbaar is voor de vertex shader. Een standaard MetaHuman-skelet bevat meer dan 600 bones, wat de mobiele limieten gemakkelijk overschrijdt en leidt tot rendering-fouten, vertex tearing of volledige GPU-hangs.

Om deze hardwarebeperking te omzeilen, moet je de engine dwingen om de skeletal mesh chunks zo op te splitsen dat geen enkele draw call naar meer dan een specifiek aantal bones verwijst. Dit wordt bereikt door de skinning compatibility-instellingen aan te passen. Als je deze configuratie niet toepast, zullen je character-modellen niet correct skinnen op Android- en iOS-apparaten, wat resulteert in statische of zwaar vervormde meshes.

De DefaultEngine.ini configureren

Om de bone skinning limits op te lossen, moet je het DefaultEngine.ini-configuratiebestand van je project aanpassen. Je vindt dit bestand in de Config-map in de root van je project. Voeg onder de sectie [ConsoleVariables] de volgende regel toe:

[ConsoleVariables]
Compat.MAX_GPUSKIN_BONES=75

Deze console variable instrueert de shader compiler om het maximale aantal bones per skinning chunk vast te zetten op 75. Dit is een strikte hardware-limiet voor oudere of mid-range mobiele GPU's. Houd er rekening mee dat het lager instellen van deze waarde de skeletal mesh compiler dwingt om de mesh in een groter aantal chunks op te splitsen. Hoewel dit rendering-compatibiliteit oplost, betekenen meer chunks ook meer draw calls, wat de performance bottleneck kan verschuiven naar je CPU render thread.

Bone Counts verlagen en Component Stripping

Voor achtergrondpersonages of non-player characters (NPC's) die geen volledige gezichtsanimatie nodig hebben, moet je het skelet strippen. Het verwijderen van bijvoorbeeld vingers, tenen en gezichtsexpressie-bones kan het totale aantal bones van een character verlagen van meer dan 600 naar minder dan 75. Hierdoor kan de character mesh als een enkele chunk worden gerenderd zonder draw call-inflatie.

Als je ook dedicated servers inzet voor je multiplayer game, zijn client-side optimalisaties pas het halve werk. Je moet ook de server-side performance optimaliseren door rendering assets volledig te strippen. Bekijk onze stapsgewijze handleiding over how to master Unreal Engine dedicated server asset stripping om de server memory overhead te verminderen en CPU-performance te optimaliseren.

MetaHuman Hair optimaliseren: Groom Strands vs. Hair Cards

De kosten van Strand Rendering

Epic's groom strand rendering-technologie tekent individuele haarkringen dynamisch. Hoewel dit zeer gedetailleerd haar oplevert op high-end desktop GPU's, is het ongelooflijk zwaar. Strand rendering leunt op compute shader-passes voor depth sorting en shadow map-generatie, wat aanzienlijk ten koste gaat van de pixel fill rate en memory bandwidth.

Op mobiele apparaten wordt strand rendering óf helemaal niet ondersteund, óf draait het tegen onaanvaardbare kosten — vaak kost het al meer dan 15ms aan GPU-tijd voor het haar van slechts één character. Mobiele GPU's missen de ruwe memory bandwidth die nodig is om honderdduizenden individuele haarcurves per frame te sorteren en te shaden.

Hair Cards implementeren

De oplossing is om strand-based grooms in te ruilen voor hair cards. Hair cards tonen haar met behulp van platte, vereenvoudigde polygon meshes die zijn gemapped met pre-rendered haartexturen. Deze aanpak is uitstekend compatibel met het mobile forward render path.

Om hair cards te implementeren, open je de MetaHuman Creator en zorg je ervoor dat je de card-based groom LOD's voor je character genereert. Het vervangen van strand-based haar door card-based grooms vermindert de rendering-tijd voor het haar van een enkele character van ongeveer 18,2ms naar 0,9ms op een moderne mobiele chip zoals de Apple A15 of Snapdragon 8 Gen 1. Deze enorme besparing stelt je in staat om rendering-budgetten toe te wijzen aan gameplay-elementen of omgevingsdetails.

Post-Process Anim Blueprints uitschakelen

MetaHumans gebruiken post-process animation blueprints om secundaire bone-bewegingen, corrigerende spiervormen en gewrichtsdynamiek aan te sturen. Hoewel dit realistische huidbewegingen toevoegt op PC, voert het elke frame complexe skeletal berekeningen uit op de CPU. Op mobiel kan deze CPU overhead de game thread gemakkelijk bottlenecken.

Je kunt de post-process animation blueprint op mobiele apparaten uitschakelen om CPU-cycles terug te winnen. Dit doe je door bDisablePostProcessAnims = true in te stellen op de skeletal mesh-componenten. Het uitschakelen van deze post-processes bespaart tot wel 4,5ms aan CPU-frametijd op standaard mobiele hardware.

PCG optimaliseren voor mobiele omgevingen

De overhead van runtime PCG-executie

Het Procedural Content Generation (PCG)-framework stelt je in staat om je omgevingen dynamisch te vullen door static meshes, foliage en actors te verspreiden op basis van regels en volumes. Het uitvoeren van PCG-graphs tijdens runtime op mobiele CPU's veroorzaakt echter ernstige performance hitches. Een typische runtime graph-generatie kan de game thread 1,5 tot 3 seconden bevriezen tijdens het laden van een level of het spawnen van spelers.

In een multiplayer game is zo'n hitch gevaarlijk; het kan leiden tot packet loss en een client-server state desynchronisation triggeren. Om een hoge performance te behouden, moet je je PCG-graphs pre-baken in de editor. Dit zet de procedurale instances om in statische geometrie voordat je je game packaged.

Stapsgewijze PCG Baking Workflow

  1. Selecteer het PCG Volume: Selecteer in de Unreal Editor viewport het PCG-volume dat je omgevingselementen bevat.
  2. Genereer en inspecteer: Klik in het details panel van het volume op Generate om een preview te zien van de procedurale plaatsing van je assets.
  3. Exporteer naar Actor: Zoek de optie Export to Actor in het PCG utilities-menu.
  4. Kies Instanced Meshes: Selecteer Hierarchical Instanced Static Mesh (HISM) als doelformaat. Deze groep instances is sterk geoptimaliseerd voor mobiele GPU's, omdat het alle identieke meshes tekent in een enkele GPU draw call.
  5. Wis de Graph: Stel na het exporteren de generation trigger van het PCG-volume in op Editor Only of wis het volume. Dit voorkomt dat de runtime engine probeert de graph opnieuw te maken.

Dynamische HISM Culling en Streaming

Zodra je je PCG-instances in HISM's hebt gebakken, moet je hun culling distances configureren. HISM's ondersteunen per-instance culling, wat betekent dat instances buiten een bepaalde afstand van de camera niet worden getekend. Stel de Start Cull Distance en End Cull Distance in in het details panel van je HISM-componenten. Voor mobiel wordt een cull distance van 5000 tot 8000 units aanbevolen om het totale aantal zichtbare polygonen binnen het budget van de mobiele GPU te houden.

Production C++ Optimization Script

Om deze optimalisaties tijdens runtime te automatiseren, kun je een custom helper class schrijven. De volgende C++-code laat zien hoe je het doelplatform controleert, programmatisch lage LOD's afdwingt, post-process animation blueprints uitschakelt en groom-componenten dwingt om card-based rendering te gebruiken bij het spawnen van een MetaHuman op een mobiel apparaat. Je kunt dit implementeren in een class zoals 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
    }
};

Deze helperfunctie kan worden aangeroepen vanuit het BeginPlay-event van je character of onmiddellijk na het spawnen van een MetaHuman-actor. Door gebruik te maken van conditional compilation macros (PLATFORM_ANDROID || PLATFORM_IOS) verwijdert de compiler deze overrides uit PC- en console-builds, waardoor je automatisch de cross-platform visuele kwaliteit behoudt.

Substrate-materialen aanpassen voor mobiele GPU's

Wat is Substrate?

Substrate vervangt het traditionele Unreal Engine shading model door een modulair, multi-layered material framework. Substrate stelt developers in staat om meerdere shading slabs te stapelen (bijvoorbeeld het plaatsen van een glanzende clear coat-laag direct over een ruwe metaallaag). Hoewel Substrate uitstekend is voor high-end cinematografische assets, vormt het een serieus performance-obstakel voor mobile renderers.

Mobiele GPU's leunen zwaar op tiled rendering-architecturen waarbij de memory bus tussen de GPU-core en de on-chip frame buffer een belangrijke bottleneck is. Complexe Substrate-materialen verhogen het aantal bytes per pixel (BPP) dat naar de frame buffer wordt geschreven, wat leidt tot thermal throttling en framerate-drops.

Material Complexity beheren via Quality Level Switches

Om te zorgen dat Substrate-materialen performant blijven op mobiel, moet je de Material Quality Level Switch- en Feature Level Switch-nodes gebruiken in de Material Editor. Met deze nodes kun je de material graph vereenvoudigen op basis van het doelplatform.

Vereenvoudig voor mobiele platforms de graph door multi-layered Substrate-blends te omzeilen. Val in plaats daarvan terug op een enkele slab die de visuele stijl van je asset benadert. Door je material nodes via een quality switch te leiden, kun je de write bandwidth verminderen van 32 bytes per pixel naar een standaard 8 bytes per pixel, wat resulteert in een koeler apparaat en stabiele framerates.

5 Actionable Best Practices voor Mobile Optimization

  1. Pre-bake alle PCG-graphs in HISM's: Voer PCG-graphs tijdens runtime niet uit op de client. Pre-bake graphs in Hierarchical Instanced Static Meshes (HISM's) tijdens de ontwikkeling in de editor en configureer de juiste start/end cull distances.
  2. Beperk bone counts globaal: Voeg Compat.MAX_GPUSKIN_BONES=75 toe aan het DefaultEngine.ini-bestand van je project om ervoor te zorgen dat skeletal meshes correct worden gerenderd op mobiele GPU's zonder buffer overflows te veroorzaken.
  3. Gebruik uitsluitend card-based grooms: Schakel strand-based grooms uit voor mobiele profielen. Card-based hair rendering vermindert de GPU-frametijd van 18ms naar minder dan 1ms per character.
  4. Benut Material Quality Switches: Implementeer de Material Quality Level Switch-node in je Substrate-materialen om complexe shading-lagen op mobiele platforms te vereenvoudigen tot een enkele slab, waardoor de GPU-bandbreedte wordt verminderd.
  5. Schakel post-process animation blueprints uit: Stel bDisablePostProcessAnims = true in op de skeletal componenten van je character op mobiel om kostbare CPU-cycles terug te winnen op de game thread.

De multiplayer- en backend-vergelijking

Meer dan rendering: Mobile Network Optimization

Bij het ontwikkelen van cross-platform multiplayer games zijn client-side optimalisaties slechts een deel van het verhaal. Mobiele apparaten hebben vaak te maken met netwerkschommelingen en schakelen voortdurend tussen mobiele data (5G/4G) en wifi. Deze fluctuaties introduceren packet loss, jitter en hoge latency spikes.

Als je netwerksynchronisatiecode niet robuust is, kunnen deze latency spikes the Unreal Engine multiplayer sync bug triggeren, waardoor actor replication uit de pas loopt en de world state breekt. Het beheren van multiplayer states onder mobiele netwerkbeperkingen is een complex probleem dat veerkrachtige netwerkdrivers, delta compression en server-authoritative reconciliation vereist.

Infrastructuur ontlasten met horizOn

Het zelf bouwen en onderhouden van een veerkrachtige multiplayer backend is een enorme technische opgave. Je moet load balancers inrichten, wereldwijde databasereplicatie beheren, matchmaking-logica implementeren en mobiele facturatie afhandelen. Dit infrastructuurwerk kan maanden ontwikkeltijd kosten en vereist doorlopend onderhoud.

Met horizOn zijn deze backend-services vooraf geconfigureerd. horizOn biedt game developers direct uit de doos session matchmaking, low-latency state-synchronisatie, database-persistentie en cross-platform authenticatie. Hierdoor kun je je concentreren op het optimaliseren van je clients en het oppoetsen van je game loop, in plaats van het beheren van serverclusters en databaseschaalbaarheid.

Conclusie en volgende stappen

Het optimaliseren van next-generation features zoals MetaHumans en PCG voor mobiel vereist strikte controle over rendering-budgetten, skeletal mesh compilation en de complexiteit van material shading. Door je procedurale assets te pre-baken, bone count-limieten te beperken en card-based hair rendering te gebruiken, kun je hoogwaardige cross-platform ervaringen leveren op handheld apparaten.

Klaar om je multiplayer backend op te schalen? Probeer horizOn gratis of bekijk de API docs om te zien hoe je je infrastructuur kunt vereenvoudigen en je spelers gesynchroniseerd kunt houden op PC, console en mobiel.


Bron: Tutorial: Optimizing Next Gen Features for Mobile Game Development