Delen via


Prestatieaanaanveling voor Unity

Dit artikel is gebaseerd op de prestatieaanbeveling voor mixed reality, maar is gericht op Unity-specifieke verbeteringen.

We hebben onlangs een toepassing uitgebracht met de naam Quality Fundamentals die betrekking heeft op veelvoorkomende prestatie-, ontwerp- en omgevingsproblemen en -oplossingen voor HoloLens 2-apps. Deze app is een geweldige visuele demo voor de inhoud die volgt.

De belangrijkste eerste stap bij het optimaliseren van de prestaties van mixed reality-apps in Unity is om ervoor te zorgen dat u de aanbevolen omgevingsinstellingen voor Unity gebruikt. Dit artikel bevat inhoud met enkele van de belangrijkste scèneconfiguraties voor het bouwen van krachtige Mixed Reality-apps. Sommige van deze aanbevolen instellingen worden hieronder ook gemarkeerd.

Profileer met Unity

Unity biedt de ingebouwde Unity Profiler , een uitstekende resource voor het verzamelen van waardevolle prestatie-inzichten voor uw specifieke app. Hoewel u de profiler in editor kunt uitvoeren, vertegenwoordigen deze metrische gegevens niet de echte runtime-omgeving, zodat de resultaten voorzichtig moeten worden gebruikt. U wordt aangeraden uw toepassing extern te profilen tijdens het uitvoeren op het apparaat voor de meest nauwkeurige en bruikbare inzichten.

Unity biedt geweldige documentatie voor:

  1. De Unity Profiler op afstand verbinden met UWP-toepassingen
  2. Prestatieproblemen met de Unity Profiler effectief diagnosticeren

GPU-profilering

Unity Profiler

Met de Unity Profiler verbonden en na het toevoegen van de GPU profiler (zie Profiler toevoegen in de rechterbovenhoek), kunt u zien hoeveel tijd wordt besteed aan respectievelijk de CPU en GPU in het midden van de profiler. Hierdoor kan de ontwikkelaar een snelle benadering krijgen als de toepassing is gebonden aan CPU of GPU.

Unity CPU versus GPU

Notitie

Als u GPU-profilering wilt gebruiken, moet u Graphics Jobs uitschakelen in de Unity Player Instellingen. Zie de GPU Usage Profiler-module van Unity voor meer informatie.

Unity Frame-foutopsporingsprogramma

Het Frame Debugger van Unity is ook een krachtig en inzichtelijk hulpprogramma dat u kunt gebruiken. Het geeft u een goed overzicht van wat de GPU doet elk frame. Dingen die u moet bekijken, zijn extra renderingdoelen en blit-opdrachten om ertussen te kopiëren, omdat deze erg duur zijn op HoloLens. In het ideale geval moeten er geen doelen voor schermweergave worden gebruikt op HoloLens. Deze worden meestal toegevoegd bij het inschakelen van dure renderingfuncties (bijvoorbeeld MSAA, HDR of effecten op volledig scherm zoals bloei) die moeten worden vermeden.

Overlay van HoloLens-framesnelheid

De pagina Systeemprestaties van de apparaatportal bevat een goed overzicht van de CPU- en GPU-prestaties van het apparaat. U kunt de teller voor de weergaveframesnelheid inschakelen in de headset en de grafiek voor de weergaveframesnelheid in de headset. Met deze opties kunt u respectievelijk een FPS-teller en grafiek inschakelen die u onmiddellijk feedback geven in elke actieve toepassing op uw apparaat.

PIX

PIX kan ook worden gebruikt om Unity-toepassingen te profileren. Er zijn ook gedetailleerde instructies voor het gebruik en installeren van PIX voor HoloLens 2. In een build voor ontwikkeling worden dezelfde bereiken weergegeven in het Frame Debugger van Unity in PIX en kunnen ze in meer detail worden geïnspecteerd en geprofileerd.

Notitie

Unity biedt de mogelijkheid om de doelresolutie van de render tijdens runtime van uw toepassing te wijzigen via de eigenschap XR Instellingen.renderViewportScale. De uiteindelijke afbeelding die op het apparaat wordt weergegeven, heeft een vaste resolutie. Op het platform wordt de uitvoer met een lagere resolutie gesampleert om een afbeelding met een hogere resolutie te maken voor rendering op beeldschermen.

UnityEngine.XR.XRSettings.renderViewportScale = 0.7f;

Aanbevelingen voor CPU-prestaties

De onderstaande inhoud bevat meer diepgaande prestatieprocedures, met name gericht op Unity & C#-ontwikkeling.

Cacheverwijzingen

We raden u aan verwijzingen naar alle relevante onderdelen en GameObjects bij initialisatie op te slaan, omdat herhalende functie-aanroepen zoals GetComponent<T>() en Camera.main duurder zijn ten opzichte van de geheugenkosten om een aanwijzer op te slaan. . Camera.main maakt gewoon gebruik van FindGameObjectsWithTag() eronder, waardoor uw scènegrafiek kostbaar wordt doorzocht naar een cameraobject met de tag MainCamera .

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour
{
    private Camera cam;
    private CustomComponent comp;

    void Start() 
    {
        cam = Camera.main;
        comp = GetComponent<CustomComponent>();
    }

    void Update()
    {
        // Good
        this.transform.position = cam.transform.position + cam.transform.forward * 10.0f;

        // Bad
        this.transform.position = Camera.main.transform.position + Camera.main.transform.forward * 10.0f;

        // Good
        comp.DoSomethingAwesome();

        // Bad
        GetComponent<CustomComponent>().DoSomethingAwesome();
    }
}

Notitie

GetComponent(tekenreeks) vermijden
Wanneer u GetComponent() gebruikt, zijn er een aantal verschillende overbelastingen. Het is belangrijk om altijd de op type gebaseerde implementaties te gebruiken en nooit de op tekenreeks gebaseerde zoekoverbelasting. Zoeken op tekenreeks in uw scène is aanzienlijk duurder dan zoeken op type.
(Goed) Component GetComponent(Type type)
(Goed) T GetComponent<T>()
(Slecht) Component GetComponent(string)>

Vermijd dure bewerkingen

  1. Vermijd het gebruik van LINQ

    Hoewel LINQ schoon en gemakkelijk te lezen en schrijven kan zijn, vereist het over het algemeen meer rekenkracht en geheugen dan als u het algoritme handmatig hebt geschreven.

    // Example Code
    using System.Linq;
    
    List<int> data = new List<int>();
    data.Any(x => x > 10);
    
    var result = from x in data
                 where x > 10
                 select x;
    
  2. Algemene Unity-API's

    Bepaalde Unity-API's, hoewel nuttig, kunnen duur zijn om uit te voeren. De meeste hiervan zijn het doorzoeken van uw hele scènegrafiek voor een overeenkomende lijst met GameObjects. Deze bewerkingen kunnen over het algemeen worden vermeden door verwijzingen in de cache te plaatsen of een manageronderdeel voor de GameObjects te implementeren om de verwijzingen tijdens runtime bij te houden.

        GameObject.SendMessage()
        GameObject.BroadcastMessage()
        UnityEngine.Object.Find()
        UnityEngine.Object.FindWithTag()
        UnityEngine.Object.FindObjectOfType()
        UnityEngine.Object.FindObjectsOfType()
        UnityEngine.Object.FindGameObjectsWithTag()
        UnityEngine.Object.FindGameObjectsWithTag()
    

Notitie

SendMessage() en BroadcastMessage() moeten worden geëlimineerd tegen alle kosten. Deze functies kunnen in de volgorde van 1000x trager zijn dan directe functieaanroepen.

  1. Pas op voor boksen

    Boksen is een kernconcept van de C#-taal en runtime. Het is het proces van het verpakken van variabelen met een waardetype, zoals char, intbool, enzovoort, in variabelen met verwijzingstypen. Wanneer een variabele met een waardetype 'boxed' is, wordt deze verpakt in een System.Object, die wordt opgeslagen op de beheerde heap. Geheugen wordt toegewezen en uiteindelijk wanneer verwijderd moet worden verwerkt door de garbagecollector. Deze toewijzingen en deallocaties kosten een prestatiekosten en in veel scenario's zijn onnodig of kunnen eenvoudig worden vervangen door een goedkoper alternatief.

    Om boksen te voorkomen, moet u ervoor zorgen dat de variabelen, velden en eigenschappen waarin u numerieke typen en structs (inclusief Nullable<T>) opslaat, sterk zijn getypt als specifieke typen, zoals int, float? of MyStruct, in plaats van object te gebruiken. Als u deze objecten in een lijst plaatst, moet u een sterk getypte lijst gebruiken, zoals List<int> in plaats List<object> van of ArrayList.

    Voorbeeld van boksen in C#

    // boolean value type is boxed into object boxedMyVar on the heap
    bool myVar = true;
    object boxedMyVar = myVar;
    

Herhalende codepaden

Herhalende Unity-callbackfuncties (d.w. Update) die vaak per seconde en/of frame worden uitgevoerd, moeten zorgvuldig worden geschreven. Alle dure bewerkingen hier hebben een enorme en consistente invloed op de prestaties.

  1. Lege callback-functies

    Hoewel de onderstaande code onschuldig kan lijken om in uw toepassing te blijven, met name omdat elk Unity-script automatisch initialiseert met een Update-methode, kunnen deze lege callbacks duur worden. Unity werkt heen en weer tussen een niet-beheerde en beheerde codegrens, tussen UnityEngine-code en uw toepassingscode. Contextoverschakeling over deze brug is redelijk duur, zelfs als er niets kan worden uitgevoerd. Dit wordt vooral problematisch als uw app 100s GameObjects heeft met onderdelen met lege herhalende Unity-callbacks.

    void Update()
    {
    }
    

Notitie

Update() is de meest voorkomende manifestatie van dit prestatieprobleem, maar andere herhalende Unity-callbacks, zoals het volgende, kunnen even slecht zijn, als dat niet erger is: FixedUpdate(), LateUpdate(), OnPostRender", OnPreRender(), OnRenderImage(), enzovoort.

  1. Bewerkingen om één keer per frame uit te voeren

    De volgende Unity-API's zijn veelvoorkomende bewerkingen voor veel Holographic Apps. Hoewel dit niet altijd mogelijk is, kunnen de resultaten van deze functies vaak eenmaal worden berekend en kunnen de resultaten opnieuw worden gebruikt in de toepassing voor een bepaald frame.

    a) Het is een goede gewoonte om een speciale Singleton-klasse of -service te hebben voor het afhandelen van raycast in de scène en dit resultaat vervolgens opnieuw te gebruiken in alle andere scèneonderdelen, in plaats van herhaalde en identieke Raycast-bewerkingen door elk onderdeel te maken. Voor sommige toepassingen zijn mogelijk raycasts van verschillende oorsprongen of tegen verschillende LayerMasks vereist.

        UnityEngine.Physics.Raycast()
        UnityEngine.Physics.RaycastAll()
    

    b) Vermijd GetComponent()-bewerkingen in herhaalde Unity-callbacks, zoals Update() door verwijzingen in de cache op te slaan in Start() of Awake()

        UnityEngine.Object.GetComponent()
    

    c) Het is raadzaam om bij het initialiseren van alle objecten, indien mogelijk, objectgroepen te initialiseren en te gebruiken om GameObjects gedurende runtime van uw toepassing te recyclen en opnieuw te gebruiken

        UnityEngine.Object.Instantiate()
    
  2. Interfaces en virtuele constructies vermijden

    Het aanroepen van functie-aanroepen via interfaces versus directe objecten of het aanroepen van virtuele functies kan vaak veel duurder zijn dan het gebruik van directe constructies of directe functie-aanroepen. Als de virtuele functie of interface niet nodig is, moet deze worden verwijderd. De prestatietreffer voor deze benaderingen is echter de moeite waard als het gebruik ervan vereenvoudigt de ontwikkelingssamenwerking, de leesbaarheid van code en de onderhoudbaarheid van code.

    Over het algemeen is het raadzaam om velden en functies niet als virtueel te markeren, tenzij er een duidelijke verwachting is dat dit lid moet worden overschreven. Een moet vooral voorzichtig zijn met betrekking tot paden met een hoge frequentie die vaak per frame of zelfs eenmaal per frame worden aangeroepen, zoals een UpdateUI() methode.

  3. Vermijd het doorgeven van structs op waarde

    In tegenstelling tot klassen zijn structs waardetypen en wanneer ze rechtstreeks aan een functie worden doorgegeven, worden de inhoud gekopieerd naar een nieuw gemaakt exemplaar. Met deze kopie worden cpu-kosten en extra geheugen aan de stack toegevoegd. Voor kleine structs is het effect minimaal en dus acceptabel. Voor functies die echter herhaaldelijk elk frame hebben aangeroepen, evenals functies die grote structs gebruiken, wijzigt u indien mogelijk de functiedefinitie zodat deze wordt doorgegeven doorverwijzing. Klik hier voor meer informatie

Diversen

  1. Natuurkunde

    a) Over het algemeen is de eenvoudigste manier om de natuurkunde te verbeteren de hoeveelheid tijd die is besteed aan fysica of het aantal iteraties per seconde te beperken. Dit vermindert de nauwkeurigheid van de simulatie. Zie TimeManager in Unity

    b) De typen colliders in Unity hebben veel verschillende prestatiekenmerken. In de onderstaande volgorde worden de meest presterende colliders vermeld voor de minst presterende colliders van links naar rechts. Het is belangrijk om Mesh Colliders te vermijden, die aanzienlijk duurder zijn dan de primitieve colliders.

    Sphere < Capsule < Box <<< Mesh (Convex) < Mesh (niet-Convex)

    Zie Best Practices voor Unity Physics voor meer informatie

  2. Animaties

    Schakel niet-actieve animaties uit door het Component Van DeN uit te schakelen (als u het gameobject uitschakelt, heeft dit niet hetzelfde effect). Vermijd ontwerppatronen waarbij een tenant zich in een lus bevindt en een waarde instelt op hetzelfde. Er is aanzienlijke overhead voor deze techniek, zonder dat dit van invloed is op de toepassing. Klik hier voor meer informatie.

  3. Complexe algoritmen

    Als uw toepassing complexe algoritmen gebruikt, zoals inverse kinematica, padzoekopdrachten, enzovoort, zoekt u een eenvoudigere benadering of past u relevante instellingen aan voor hun prestaties

Aanbevelingen voor CPU-naar-GPU-prestaties

Over het algemeen komen de CPU-naar-GPU-prestaties neer op de tekenoproepen die naar de grafische kaart worden verzonden. Om de prestaties te verbeteren, moeten aanroepen strategisch a) verminderd of b) worden geherstructureerd voor optimale resultaten. Omdat tekenoproepen zelf resource-intensief zijn, vermindert u het totale werk dat nodig is. Bovendien vereisen statuswijzigingen tussen aanroepen dure validatie- en vertaalstappen in het grafische stuurprogramma en kunnen de herstructurering van de tekenoproepen van uw toepassing om statuswijzigingen te beperken (d.w.z. verschillende materialen, enzovoort) de prestaties verbeteren.

Unity heeft een geweldig artikel met een overzicht en duikt in batchverwerkingsaanvragen voor hun platform.

Rendering met exemplaar van één wachtwoord

Met Single Pass Instanced Rendering in Unity kunnen oproepen voor elk oog worden verkleind tot één geexempeerde tekenoproep. Vanwege coherentie in de cache tussen twee aanroepen tekenen, is er ook een verbetering in de prestaties van de GPU.

Deze functie inschakelen in uw Unity-project

  1. OpenXR-Instellingen (ga naar Project bewerken>Instellingen> XR Plugin Management>OpenXR).
  2. Selecteer Single Pass Instanced in de vervolgkeuzelijst Render Mode .

Lees de volgende artikelen uit Unity voor meer informatie met deze renderingbenadering.

Notitie

Een veelvoorkomend probleem met Single Pass Instanced Rendering treedt op als ontwikkelaars al bestaande aangepaste shaders hebben die niet zijn geschreven voor instancing. Nadat deze functie is ingeschakeld, kunnen ontwikkelaars merken dat sommige GameObjects slechts in één oog worden weergegeven. Dit komt doordat de bijbehorende aangepaste shaders niet over de juiste eigenschappen beschikken voor instancing.

Statische batchverwerking

Unity kan veel statische objecten batchgewijs batcheren om tekenoproepen naar de GPU te verminderen. Statische batchverwerking werkt voor de meeste Renderer-objecten in Unity die 1) hetzelfde materiaal delen en 2) zijn allemaal gemarkeerd als statisch (selecteer een object in Unity en schakel het selectievakje in de rechterbovenhoek van de inspector in). GameObjects die zijn gemarkeerd als Statisch , kunnen niet worden verplaatst tijdens de runtime van uw toepassing. Statische batchverwerking kan dus moeilijk worden gebruikt op HoloLens waar vrijwel elk object moet worden geplaatst, verplaatst, geschaald, enzovoort. Voor insluitende headsets kan statische batchverwerking de tekenoproepen aanzienlijk verminderen en zo de prestaties verbeteren.

Lees statische batchverwerking onder Draw Call Batching in Unity voor meer informatie.

Dynamische batchverwerking

Omdat het problematisch is om objecten te markeren als statisch voor HoloLens-ontwikkeling, kan dynamische batchverwerking een uitstekend hulpmiddel zijn om te compenseren voor deze ontbrekende functie. Het kan ook handig zijn voor insluitende headsets. Dynamische batchverwerking in Unity kan echter moeilijk zijn in te schakelen omdat GameObjects hetzelfde materiaal moet delen en b) voldoen aan een lange lijst met andere criteria.

Lees dynamische batchverwerking onder Draw Call Batching in Unity voor de volledige lijst. GameObjects worden meestal dynamisch ongeldig om dynamisch te worden gebatcheerd, omdat de bijbehorende mesh-gegevens niet meer dan 300 hoekpunten kunnen zijn.

Andere technieken

Batchverwerking kan alleen optreden als meerdere GameObjects hetzelfde materiaal kunnen delen. Normaal gesproken wordt dit geblokkeerd door de noodzaak voor GameObjects om een unieke textuur te hebben voor hun respectieve materiaal. Het is gebruikelijk om texturen te combineren tot één grote texture, een methode die bekend staat als Texture Atlasing.

Bovendien is het beter om waar mogelijk en redelijk meshes te combineren in één GameObject. Elke Renderer in Unity heeft de bijbehorende tekenoproep(en) versus het verzenden van een gecombineerde mesh onder één Renderer.

Notitie

Als u eigenschappen van Renderer.material tijdens runtime wijzigt, wordt er een kopie van het materiaal gemaakt en wordt batchverwerking mogelijk verbroken. Gebruik Renderer.sharedMaterial om gedeelde materiaaleigenschappen in GameObjects te wijzigen.

Aanbevelingen voor GPU-prestaties

Meer informatie over het optimaliseren van grafische rendering in Unity

Bandbreedte- en vulsnelheden

Bij het weergeven van een frame op de GPU is een toepassing gebonden aan geheugenbandbreedte of vulsnelheid.

  • Geheugenbandbreedte is de snelheid van lees- en schrijfbewerkingen die de GPU kan uitvoeren vanuit het geheugen
  • Vulsnelheid verwijst naar de pixels die per seconde door de GPU kunnen worden getekend.
    • Gebruik in Unity de eigenschap XR Instellingen.renderViewportScale.

Dieptebuffer delen optimaliseren

U wordt aangeraden dieptebuffer delen in te schakelen om te optimaliseren voor hologramstabiliteit. Bij het inschakelen van op diepte gebaseerde latere projectie met deze instelling wordt u aangeraden een 16-bits diepteindeling te selecteren in plaats van een 24-bits diepteindeling. De 16-bits dieptebuffers verminderen de bandbreedte (en dus stroom) die samenhangen met dieptebufferverkeer drastisch. Dit kan een grote verbetering zijn in zowel energieverbruikvermindering als prestaties. Er zijn echter twee mogelijke negatieve resultaten met behulp van de 16-bits diepteindeling.

Z-Fighting

De verminderde betrouwbaarheid van het dieptebereik maakt z-vechten waarschijnlijker met 16 bits dan 24-bits. Om deze artefacten te voorkomen, wijzigt u de knipvlakken van de Unity-camera om rekening te houden met de lagere precisie. Voor HoloLens-toepassingen kan een verre clipvlak van 50 m in plaats van de Unity-standaard 1000 m over het algemeen alle z-gevechten elimineren.

Uitgeschakelde stencilbuffer

Wanneer Unity een Render Texture met 16-bits diepte maakt, is er geen stencilbuffer gemaakt. Als u de 24-bits diepteindeling selecteert, zoals beschreven in de Unity-documentatie, wordt er een 24-bits z-buffer en een 8-bits stencilbuffer gemaakt (als 32-bits van toepassing is op een apparaat (bijvoorbeeld de HoloLens), wat in het algemeen het geval is).

Effecten op volledig scherm voorkomen

Technieken die op het volledige scherm werken, kunnen duur zijn, omdat hun grootte van miljoenen bewerkingen elk frame is. Het wordt aanbevolen om naverwerkingseffecten zoals antialiassen, bloei en meer te voorkomen.

Optimale belichtingsinstellingen

Realtime Global Lighting in Unity kan uitstekende visuele resultaten opleveren, maar omvat dure belichtingsberekeningen. We raden u aan real-time Global Lighting uit te schakelen voor elk Unity-scènebestand via Window>Rendering>Lighting Instellingen> Schakel realtime globale verlichting uit.

Bovendien is het raadzaam om alle schaduwcasting uit te schakelen, omdat deze ook dure GPU-passes toevoegen aan een Unity-scène. Schaduwen kunnen per licht worden uitgeschakeld, maar kunnen ook holistisch worden beheerd via kwaliteitsinstellingen.

Bewerk>Project Instellingen en selecteer vervolgens de categorie > Kwaliteit selecteren Lage kwaliteit voor het UWP-platform. U kunt ook de eigenschap Schaduwen instellen op Schaduwen uitschakelen.

We raden u aan gebakken verlichting te gebruiken met uw modellen in Unity.

Aantal polys verminderen

Het aantal veelhoeken wordt verminderd door een van beide

  1. Objecten uit een scène verwijderen
  2. Activumdeciatie, wat het aantal veelhoeken voor een gegeven mesh vermindert
  3. Het implementeren van een LOD-systeem (Level of Detail) in uw toepassing, waarmee verre objecten met een lagere polygonversie van dezelfde geometrie worden weergegeven

Shaders in Unity begrijpen

Een eenvoudige benadering om shaders in prestaties te vergelijken, is door het gemiddelde aantal bewerkingen te identificeren dat tijdens runtime wordt uitgevoerd. Dit kan eenvoudig worden gedaan in Unity.

  1. Selecteer uw shader-asset of selecteer een materiaal en selecteer vervolgens in de rechterbovenhoek van het controlevenster het tandwielpictogram, gevolgd door 'Shader selecteren'

    Shader selecteren in Unity

  2. Als de shader-asset is geselecteerd, selecteert u de knop Compileren en code weergeven onder het inspectorvenster

    Shader-code compileren in Unity

  3. Zoek na het compileren naar de sectie Statistieken in de resultaten met het aantal verschillende bewerkingen voor zowel het hoekpunt als de pixel-shader (Opmerking: pixel-shaders worden ook wel fragment shaders genoemd)

    Unity Standard Shader-bewerkingen

Pixel-shaders optimaliseren

Als u de gecompileerde statistische resultaten bekijkt met behulp van de bovenstaande methode, voert de fragment-shader doorgaans meer bewerkingen uit dan de hoekpunt-shader, gemiddeld. De fragment-shader, ook wel de pixel-shader genoemd, wordt uitgevoerd per pixel op de schermuitvoer, terwijl de hoekpunt-shader alleen per hoekpunt wordt uitgevoerd van alle meshes die op het scherm worden getekend.

Fragment shaders hebben dus niet alleen meer instructies dan hoekpunt-shaders vanwege alle belichtingsberekeningen, fragment shaders worden bijna altijd uitgevoerd op een grotere gegevensset. Als de schermuitvoer bijvoorbeeld een 2k bij 2k-afbeelding is, kan de fragment-shader 2.000*2.000 = 4.000.000 keer worden uitgevoerd. Als twee ogen worden weergegeven, verdubbelt dit getal omdat er twee schermen zijn. Als een mixed reality-toepassing meerdere geslaagde, naverwerkingseffecten op volledig scherm heeft of meerdere meshes tot dezelfde pixel weergeeft, neemt dit aantal aanzienlijk toe.

Daarom kan het verminderen van het aantal bewerkingen in de fragment-shader over het algemeen veel betere prestaties opleveren dan optimalisaties in de hoekpunt-shader.

Alternatieven voor Unity Standard-shader

In plaats van een fysiek gebaseerde rendering (PBR) of een andere arcering van hoge kwaliteit te gebruiken, kijkt u naar het gebruik van een krachtigere en goedkopere shader. De Mixed Reality Toolkit biedt de MRTK-standaard-shader die is geoptimaliseerd voor mixed reality-projecten.

Unity biedt ook een niet-verlicht, hoekpunt verlicht, diffuus en andere vereenvoudigde shader-opties die sneller zijn vergeleken met de Unity Standard-shader. Zie Het gebruik en de prestaties van ingebouwde shaders voor meer gedetailleerde informatie.

Arcering vooraf laden

Gebruik Shader-preloading en andere trucs om de laadtijd van de shader te optimaliseren. Met name shader preloading betekent dat u geen hitches ziet vanwege runtime-shader-compilatie.

Limiet voor overtekening

In Unity kunt u overtekening voor hun scène weergeven door het menu Tekenmodus in de linkerbovenhoek van de scèneweergave in te schakelen en Overdraw te selecteren.

Over het algemeen kan het overschrijven worden verzacht door objecten van tevoren te ruimen voordat ze naar de GPU worden verzonden. Unity biedt details over het implementeren van Occlusion Culling voor hun motor.

Aanbevelingen voor geheugen

Overmatige geheugentoewijzing en deallocatiebewerkingen kunnen nadelige gevolgen hebben voor uw holografische toepassing, wat resulteert in inconsistente prestaties, bevroren frames en ander schadelijk gedrag. Het is vooral belangrijk om inzicht te hebben in geheugenoverwegingen bij het ontwikkelen in Unity, omdat geheugenbeheer wordt beheerd door de garbagecollector.

Garbagecollection

Holographic-apps verliezen de rekentijd voor de garbagecollector (GC) wanneer de GC wordt geactiveerd om objecten te analyseren die niet langer binnen het bereik vallen tijdens de uitvoering en hun geheugen moet worden vrijgegeven, zodat deze beschikbaar kan worden gesteld voor hergebruik. Voor constante toewijzingen en de toewijzingen is over het algemeen vereist dat de garbagecollector vaker wordt uitgevoerd, waardoor de prestaties en gebruikerservaring pijn doen.

Unity biedt een uitstekende pagina die in detail uitlegt hoe de garbagecollector werkt en tips voor het schrijven van efficiëntere code met betrekking tot geheugenbeheer.

Een van de meest voorkomende procedures die leiden tot overmatige garbagecollection is geen cachingverwijzingen naar onderdelen en klassen in Unity-ontwikkeling. Verwijzingen moeten worden vastgelegd tijdens Start() of Awake() en opnieuw worden gebruikt in latere functies, zoals Update() of LateUpdate().

Andere snelle tips:

  • Gebruik de klasse StringBuilder C# om tijdens runtime dynamisch complexe tekenreeksen te bouwen
  • Verwijder aanroepen naar Debug.Log() wanneer deze niet meer nodig zijn, omdat ze nog steeds worden uitgevoerd in alle buildversies van een app
  • Als uw holografische app over het algemeen veel geheugen vereist, kunt u Overwegen om System.GC.Collect() aan te roepen tijdens het laden, zoals bij het presenteren van een laad- of overgangsscherm

Objectpooling

Objectpooling is een populaire techniek voor het verminderen van de kosten van continue objecttoewijzing en deallocatie. Dit wordt gedaan door een grote groep identieke objecten toe te wijzen en inactieve, beschikbare exemplaren uit deze pool te hergebruiken in plaats van voortdurend objecten in de loop van de tijd te vernietigen en te vernietigen. Objectgroepen zijn ideaal voor hergebruikbare onderdelen met een variabele levensduur tijdens een app.

Opstartprestaties

Overweeg om uw app te starten met een kleinere scène en vervolgens ScèneManager.LoadSceneAsync te gebruiken om de rest van de scène te laden. Hierdoor kan uw app zo snel mogelijk een interactieve status krijgen. Er kan een grote CPU-piek optreden terwijl de nieuwe scène wordt geactiveerd en dat alle gerenderde inhoud stutters of hitch kan veroorzaken. Een manier om dit te omzeilen is door de eigenschap AsyncOperation.allowSceneActivation in te stellen op 'false' op de scène die wordt geladen, te wachten tot de scène is geladen, het scherm op zwart te wissen en deze vervolgens weer in te stellen op 'true' om de scèneactivering te voltooien.

Houd er rekening mee dat tijdens het laden van de opstartscène het holografische welkomstscherm wordt weergegeven aan de gebruiker.

Zie ook