Teljesítménnyel kapcsolatos javaslatok a Unityhez

Ez a cikk a vegyes valóság teljesítményére vonatkozó javaslatokra épül, de a Unity-specifikus fejlesztésekre összpontosít.

Nemrég kiadtunk egy Minőségi alapok nevű alkalmazást, amely a HoloLens 2-alkalmazások gyakori teljesítménybeli, tervezési és környezeti problémáit és megoldásait ismerteti. Ez az alkalmazás nagyszerű vizuális bemutató a következő tartalomhoz.

A vegyes valóságú alkalmazások teljesítményének a Unityben való optimalizálása során a legfontosabb első lépés annak biztosítása, hogy a Unityhez ajánlott környezeti beállításokat használja. Ez a cikk tartalmaz néhány fontos jelenetkonfigurációt a teljesítményt nyújtó Mixed Reality alkalmazások létrehozásához. Az alábbiakban néhány javasolt beállítás is ki van emelve.

Profilkészítés a Unityvel

A Unity beépített Unity Profilerrel rendelkezik, amely nagyszerű erőforrás az adott alkalmazás értékes teljesítményelemzéseinek gyűjtéséhez. Bár a profilkészítőt futtathatja a szerkesztőben, ezek a metrikák nem a valós futtatókörnyezetet jelölik, ezért az eredményeket óvatosan kell használni. Azt javasoljuk, hogy távolról profilt készítsen az alkalmazásról, miközben az eszközön fut a legpontosabb és leghatékonyabb elemzések érdekében.

A Unity nagyszerű dokumentációt nyújt az alábbiakhoz:

  1. A Unity profilkészítő csatlakoztatása UWP-alkalmazásokhoz távolról
  2. Teljesítményproblémák hatékony diagnosztizálása a Unity Profilerrel

GPU-profilkészítés

Unity profilkészítő

Ha a Unity Profiler csatlakoztatva van, és a GPU-profilozó hozzáadása után (lásd a profilkészítő hozzáadását a jobb felső sarokban), láthatja, hogy mennyi időt töltenek a CPU & GPU-val a profilkészítő közepén. Ez lehetővé teszi a fejlesztő számára, hogy gyors közelítést kapjon, ha az alkalmazás cpu- vagy GPU-keretbe van kötve.

Unity CPU és GPU

Megjegyzés

A GPU-profilkészítés használatához le kell tiltania a grafikus feladatokat a Unity Player beállításai között. További részletekért tekintse meg a Unity GPU-használati profiler modulját .

Unity-keret hibakeresője

A Unity Frame Debugger egy hatékony és éleslátó eszköz, amelyet érdemes használni. Ez jó áttekintést ad arról, hogy mit csinál a GPU az egyes kereteket. A további renderelési célokat és a közöttük másolandó blit parancsokat érdemes figyelni, mivel ezek nagyon drágák a HoloLensben. Ideális esetben a HoloLensben nem szabad képernyőkön kívüli megjelenítési célokat használni. Ezeket általában a drága renderelési funkciók (például MSAA, HDR vagy teljes képernyős effektusok, például a bloom) engedélyezésekor adják hozzá, amelyeket el kell kerülni.

HoloLens-keretsebesség átfedése

Az Eszközportál rendszerteljesítménye oldal jól összefoglalja az eszköz processzor- és GPU-teljesítményét. Engedélyezheti a Képkockasebesség-számláló megjelenítését a headsetben és a Képkockasebesség-grafikon megjelenítése a headsetben. Ezek a lehetőségek lehetővé teszik az FPS-számlálót és a gráfot, amely azonnali visszajelzést ad az eszközön futó alkalmazásokról.

Pix

A PIX a Unity-alkalmazások profilkészítésére is használható. A HoloLens 2-hez készült PIX használatára és telepítésére vonatkozó részletes utasítások is megtalálhatók. A fejlesztési buildekben a Unity Frame Debuggerben látható hatókörök is megjelennek a PIX-ben, és részletesebben is megvizsgálhatók és profilt készíthetnek.

Megjegyzés

A Unity lehetővé teszi az alkalmazás renderelési célfelbontásának egyszerű módosítását futásidőben az XRSettings.renderViewportScale tulajdonságon keresztül. Az eszközön megjelenő végső kép rögzített felbontással rendelkezik. A platform mintát vesz az alacsonyabb felbontású kimenetből, hogy egy nagyobb felbontású képet hozzon létre a megjelenítéshez.

UnityEngine.XR.XRSettings.renderViewportScale = 0.7f;

Cpu-teljesítményre vonatkozó javaslatok

Az alábbi tartalom részletesebb teljesítménnyel kapcsolatos eljárásokat tartalmaz, különösen a Unity & C#-fejlesztésre vonatkozóan.

Gyorsítótár-hivatkozások

Javasoljuk, hogy inicializáláskor gyorsítótárazza az összes releváns összetevőre és GameObjectre mutató hivatkozást, mert az ismétlődő függvényhívások, például a GetComponent<T>() és a Camera.main drágábbak a mutató tárolásának memóriaköltségéhez képest. . A Camera.main csak a FindGameObjectsWithTag() objektumot használja alatta, amely költségesen keres egy kameraobjektumot a "MainCamera" címkével.

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();
    }
}

Megjegyzés

A GetComponent(sztring) elkerülése
A GetComponent() használatakor néhány különböző túlterhelés van. Fontos, hogy mindig a Típusalapú implementációkat használja, és soha ne a sztringalapú keresési túlterhelést. A sztring alapján történő keresés a jelenetben lényegesen költségesebb, mint a típus szerinti keresés.
(Jó) Összetevő GetComponent(Típus típusa)
(Jó) T GetComponent<T>()
(Rossz) Összetevő GetComponent(sztring)>

Kerülje a költséges műveleteket

  1. A LINQ használatának elkerülése

    Bár a LINQ tiszta és könnyen olvasható és írható, általában több számítást és memóriát igényel, mint ha manuálisan írta volna az algoritmust.

    // 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. Common Unity API-k

    Bizonyos Unity API-k, bár hasznosak, költségesek lehetnek a végrehajtásukhoz. Ezek többsége magában foglalja a teljes jelenetgrafikon keresését a GameObjects egyező listájának kereséséhez. Ezek a műveletek általában elkerülhetők a hivatkozások gyorsítótárazásával vagy a GameObjects kezelői összetevőjének implementálásával a hivatkozások futásidőben történő nyomon követéséhez.

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

Megjegyzés

A SendMessage() és a BroadcastMessage() elemet minden áron el kell távolítani. Ezek a függvények 1000x lassabb sorrendben lehetnek, mint a közvetlen függvényhívások.

  1. Óvakodj a boxolástól

    A boxing a C#-nyelv és a futtatókörnyezet alapvető fogalma. Az érték típusú változók ( például char, , intboolstb.) hivatkozás típusú változókba való burkolásának folyamata. Ha egy érték típusú változó "dobozos", akkor a rendszer egy System.Object, a felügyelt halomtárban tárolja. A rendszer lefoglalja a memóriát, és végül az ártalmatlanításkor a szemétgyűjtőnek kell feldolgoznia. Ezek a foglalások és felszabadítások teljesítményköltséggel járnak, és sok esetben szükségtelenek, vagy könnyen lecserélhetők egy kevésbé költséges alternatívával.

    A dobozolás elkerülése érdekében győződjön meg arról, hogy a változók, mezők és tulajdonságok, amelyekben numerikus típusokat és szerkezeteket tárol (beleértve a elemet is Nullable<T>), szigorúan meghatározott típusként vannak begépelve, például int, float? vagy MyStruct, objektum használata helyett. Ha ezeket az objektumokat listába helyezi, ügyeljen arra, hogy erősen begépelt listát használjon, például List<int> a vagy ArrayLista helyettList<object>.

    Példa a C-ben történő boxolásra #

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

Ismétlődő kódútvonalak

Minden ismétlődő Unity-visszahívási függvényt (pl. Frissítés), amelyet másodpercenként és/vagy keretenként többször hajt végre, gondosan meg kell írni. Minden költséges műveletnek óriási és következetes hatása lesz a teljesítményre.

  1. Üres visszahívási függvények

    Bár az alábbi kód ártatlannak tűnhet az alkalmazásban, különösen mivel minden Unity-szkript automatikusan inicializálódik egy Update metódussal, ezek az üres visszahívások költségessé válhatnak. A Unity oda-vissza működik egy nem felügyelt és felügyelt kód határa, a UnityEngine-kód és az alkalmazáskód között. A híd feletti környezetváltás meglehetősen költséges, még akkor is, ha nincs mit végrehajtani. Ez különösen akkor válik problémássá, ha az alkalmazás 100 GameObjects összetevővel rendelkezik, amelyek üres ismétlődő Unity-visszahívásokkal rendelkeznek.

    void Update()
    {
    }
    

Megjegyzés

Az Update() a teljesítményprobléma leggyakoribb megnyilvánulása, de más ismétlődő Unity-visszahívások, például a következők is ugyanolyan rosszak lehetnek, ha nem rosszabbak: FixedUpdate(), LateUpdate(), OnPostRender", OnPreRender(), OnRenderImage(), stb.

  1. A futtatás keretenként egyszer történő futtatását előnyben részesítő műveletek

    Az alábbi Unity API-k gyakori műveletek számos Holographic-alkalmazáshoz. Bár nem mindig lehetséges, az ilyen függvények eredményei általában egyszer számíthatók ki, és az eredmények újra felhasználhatók az alkalmazás egészében egy adott kerethez.

    a) Érdemes egy dedikált Singleton osztályt vagy szolgáltatást használni a Raycast látványának a jelenetbe való kezeléséhez, majd ezt az eredményt újra felhasználni az összes többi jelenetösszetevőben, ahelyett, hogy az egyes összetevők ismétlődő és azonos Raycast-műveleteket végeznek. Egyes alkalmazásokhoz különböző eredetű vagy különböző LayerMasks-alapú raycast-küldésre lehet szükség.

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

    b) Kerülje a GetComponent() műveleteket ismétlődő Unity-visszahívásokban, például update() a Start() vagy a Awake() hivatkozásainak gyorsítótárazásával

        UnityEngine.Object.GetComponent()
    

    c) Célszerű az összes objektumot példányosítani, ha lehetséges, inicializáláskor, és objektumkészletezéssel újrahasznosítani és újra felhasználni a GameObjectset az alkalmazás futásidejében

        UnityEngine.Object.Instantiate()
    
  2. Interfészek és virtuális szerkezetek elkerülése

    A függvényhívások meghívása interfészeken vagy közvetlen objektumokon keresztül, illetve virtuális függvények meghívása gyakran sokkal drágább lehet, mint közvetlen szerkezetek vagy közvetlen függvényhívások használata. Ha a virtuális függvény vagy interfész szükségtelen, akkor el kell távolítani. Azonban ezeknek a megközelítéseknek a teljesítménybeli sikerét érdemes kompromisszumos megoldásnak tartani, ha azok használata leegyszerűsíti a fejlesztési együttműködést, a kód olvashatóságát és a kód karbantarthatóságát.

    Általában azt javasoljuk, hogy csak akkor jelöljön meg mezőket és függvényeket virtuálisként, ha egyértelmű elvárás, hogy ezt a tagot felül kell írni. Különösen körültekintőnek kell lennie a nagy frekvenciájú kódútvonalak körül, amelyeket keretenként többször vagy akár keretenként egyszer is meghívnak, például egy metódussal UpdateUI() .

  3. Ne adja át a szerkezeteket érték szerint

    Az osztályoktól eltérően a szerkezetek érték típusúak, és amikor közvetlenül egy függvénynek adnak át, a rendszer a tartalmát egy újonnan létrehozott példányba másolja. Ez a másolat processzorköltséget és további memóriát ad hozzá a veremhez. A kis szerkezetek esetében a hatás minimális, és így elfogadható. Ha azonban a függvények minden keretet ismételten meghívtak, valamint a nagy szerkezeteket tartalmazó függvényeket, ha lehetséges, módosítsa a függvénydefiníciót úgy, hogy hivatkozás útján haladjon át. További információ itt

Különböző veszélyes anyagok és tárgyak

  1. Fizika

    a) A fizika javításának legegyszerűbb módja általában a fizikára fordított idő vagy a másodpercenkénti iterációk számának korlátozása. Ez csökkenti a szimuláció pontosságát. A TimeManager megtekintése a Unityben

    b) A Unityben a ütközőtípusok teljesítményjellemzői széles körben eltérnek. Az alábbi sorrend a legteljesebb ütközőket sorolja fel balról jobbra a legkevésbé teljesítő ütközőkre. Fontos elkerülni a Mesh Colliderst, amelyek lényegesen drágábbak, mint a primitív ütközők.

    Sphere < Capsule < Box <<< Mesh (Convex) < Mesh (nem Konvex)

    További információ: Unity Fizika – ajánlott eljárások

  2. Animációk

    Tiltsa le a tétlen animációkat az Animator összetevő letiltásával (a játékobjektum letiltása nem lesz ugyanolyan hatással). Kerülje azokat a tervezési mintákat, amelyekben egy animátor egy hurokban ül, és ugyanazt az értéket állítja be. Ez a technika jelentős többletterhelést okoz, és nincs hatással az alkalmazásra. További információt itt talál.

  3. Összetett algoritmusok

    Ha az alkalmazás olyan összetett algoritmusokat használ, mint az inverz kinematika, az útvonalkeresés stb., keressen egyszerűbb megközelítést, vagy módosítsa a teljesítményük megfelelő beállításait

Cpu-gpu teljesítményre vonatkozó javaslatok

Általában a PROCESSZOR–GPU teljesítmény a grafikus kártyára küldött rajzhívásokra jellemző. A teljesítmény javítása érdekében a hívásokat stratégiailag a) csökkenteni kell, vagy b) át kell strukturálni az optimális eredmények érdekében. Mivel maguk a rajzhívások erőforrás-igényesek, a csökkentésük csökkenti a teljes munkaigényt. Ezenkívül a rajzhívások közötti állapotváltozások költséges érvényesítési és fordítási lépéseket igényelnek a grafikus illesztőprogramban, így az alkalmazás rajzhívásainak átszervezése az állapotváltozások (pl. különböző anyagok stb.) korlátozása érdekében növelheti a teljesítményt.

A Unity nagyszerű cikkel rendelkezik, amely áttekintést nyújt, és részletesen ismerteti a platformhoz tartozó kötegelési rajzhívásokat.

Egybemenő példányos renderelés

A Unityben a Single Pass Instanced Rendering lehetővé teszi, hogy minden szem hívása egy példányos rajzolási hívásra csökkenjen. A két rajzhívás közötti gyorsítótár-koherencia miatt a GPU-n is van némi teljesítménybeli javulás.

A funkció engedélyezése a Unity-projektben

  1. Nyissa meg az OpenXR-beállításokat (nyissa meg aProjektbeállítások>szerkesztése>XR Beépülő modulkezelés>OpenXR című szakaszt).
  2. A Renderelési mód legördülő menüben válassza a Single Pass Instanced (Egyátadásos példány) lehetőséget.

Ennek a megjelenítési módszernek a részleteiért olvassa el a Unity következő cikkeit.

Megjegyzés

A Single Pass Instanced Rendering egyik gyakori problémája akkor fordul elő, ha a fejlesztők már rendelkeznek olyan egyéni árnyékolókkal, amelyeket nem instancingra írtak. A funkció engedélyezése után a fejlesztők észrevehetik, hogy egyes GameObjects-elemek csak egy szemen belül jelennek meg. Ennek az az oka, hogy a társított egyéni árnyékolók nem rendelkeznek a megfelelő tulajdonságokkal az instancinghoz.

A probléma megoldásához lásd: Single Pass Stereo Rendering for HoloLens for Unity (Single Pass Stereo Rendering for HoloLens for Unity)

Statikus kötegelés

A Unity számos statikus objektum kötegelésére képes, hogy csökkentse a GPU-ra irányuló hívásokat. A statikus kötegelés a Unity legtöbb renderelő objektumához működik, amelyekben 1) ugyanazzal az anyaggal rendelkezik, és 2) mind statikusként vannak megjelölve (Jelöljön ki egy objektumot a Unityben, és jelölje be az ellenőr jobb felső sarkában található jelölőnégyzetet). A Statikusként megjelölt GameObjects nem helyezhető át az alkalmazás futtatókörnyezetében. Így a statikus kötegelést nehéz lehet kihasználni a HoloLensben, ahol gyakorlatilag minden objektumot el kell helyezni, áthelyezni, skálázni stb. A modern headsetek esetében a statikus kötegelés jelentősen csökkentheti a híváshívásokat, és ezáltal javíthatja a teljesítményt.

További részletekért olvassa el a Statikus kötegelés szakasz Hívási kötegelés rajzolása a Unityben szakaszát .

Dinamikus kötegelés

Mivel problémás az objektumok statikusként való megjelölése a HoloLens-fejlesztéshez, a dinamikus kötegelés kiváló eszköz lehet a hiányzó funkció kompenzálására. A modern headsetek esetében is hasznos lehet. A Unity dinamikus kötegelését azonban nehéz lehet engedélyezni, mert a GameObjectsnek ugyanazt az anyagot kell használnia , és b) meg kell felelnie a többi feltétel hosszú listájának.

Olvassa el a dinamikus kötegelést a Híváskötegelés rajzolása a Unityben területen a teljes listáért. Leggyakrabban a GameObjects érvénytelenné válik a dinamikus kötegeléséhez, mivel a társított hálóadatok legfeljebb 300 csúcspontot tartalmazhatnak.

Egyéb technikák

Kötegelés csak akkor fordulhat elő, ha több GameObjects képes megosztani ugyanazt az anyagot. Ezt általában az fogja blokkolni, hogy a GameObjectsnek egyedi anyagmintával kell rendelkeznie a megfelelő anyaghoz. Gyakori, hogy a textúra egy nagy textúra, az úgynevezett Textúra Atlasing módszer.

Ezenkívül célszerű a hálókat egy GameObjectbe egyesíteni, ahol lehetséges és ésszerű. A Unity minden renderelője rendelkezik a kapcsolódó rajzolási hívásokkal, és nem küldi el a kombinált hálót egy Renderer alatt.

Megjegyzés

A Renderer.material tulajdonságainak futásidőben történő módosítása létrehoz egy másolatot az Anyagról, és ezáltal megszakítja a kötegelést. A Renderer.sharedMaterial használatával módosíthatja a megosztott anyagok tulajdonságait a GameObjectsben.

GPU-teljesítményre vonatkozó javaslatok

További információ a grafikus renderelés optimalizálásáról a Unityben

Sávszélesség és kitöltési arány

Keret GPU-n való renderelésekor az alkalmazásokat vagy a memória sávszélessége vagy a kitöltési sebesség köti össze.

  • A memória sávszélessége a GPU által a memóriából elvégezhető olvasási és írási sebesség
  • A kitöltési sebesség a GPU által másodpercenként rajzolható képpontokra vonatkozik.

A mélységi puffermegosztás optimalizálása

Javasoljuk, hogy engedélyezze a mélységi puffermegosztást a hologram stabilitásának optimalizálásához. Ha ezzel a beállítással engedélyezi a mélységalapú késői fázisú újraprojektet, javasoljuk, hogy a 24 bites mélységi formátum helyett a 16 bites mélységi formátumot válassza. A 16 bites mélységi pufferek drasztikusan csökkentik a mélységi pufferforgalomhoz társított sávszélességet (és így a teljesítményt). Ez nagy javulást jelenthet mind az energiacsökkentésben, mind a teljesítményben. A 16 bites mélységi formátum használatával azonban két lehetséges negatív eredmény érhető el.

Z-Fighting

A csökkentett mélységi tartomány hűsége nagyobb valószínűséggel teszi a z-harcok előfordulását 16 bites, mint 24 bites. Az összetevők elkerülése érdekében módosítsa a Unity kamera közel/messze vágósíkjait úgy, hogy az alacsonyabb pontosságot is figyelembe vegyék. A HoloLens-alapú alkalmazások esetében a Unity alapértelmezett 1000 m helyett 50 m-nyi klipsíkja általában kiküszöböli a z-harcokat.

Letiltott rajzsablonpuffer

Amikor a Unity 16 bites mélységű renderelési textúrát hoz létre, nem jön létre rajzsablonpuffer. A Unity dokumentációja szerint a 24 bites mélységi formátum kiválasztásakor létrejön egy 24 bites z-puffer, valamint egy [8 bites rajzsablonpuffer] () (https://docs.unity3d.com/Manual/SL-Stencil.htmlha 32 bites alkalmazható egy eszközön, ami általában a HoloLens esete).

Teljes képernyős effektusok elkerülése

A teljes képernyőn működő technikák költségesek lehetnek, mivel nagyságrendjük keretenként több millió műveletből áll. Javasoljuk, hogy kerülje a feldolgozás utáni hatásokat , például az élsimítást, a virágzást és egyebeket.

Optimális világítási beállítások

A Unity valós idejű globális megvilágítása kiemelkedő vizuális eredményeket nyújthat, de költséges világítási számításokat is magában foglal. Azt javasoljuk, hogy tiltsa le a valós idejű globális megvilágítást minden Unity-jelenetfájl esetében azAblakmegjelenítési>>világítás beállításain> keresztül a valós idejű globális megvilágítás jelölésének megszüntetésekor.

Emellett javasoljuk, hogy tiltsa le az összes árnyékolást, mivel ezek drága GPU-átadásokat is hozzáadnak egy Unity-jelenethez. Az árnyékok fényenként letilthatók, de holisztikusan is szabályozhatók a minőségi beállításokon keresztül.

Szerkesztése>Projektbeállítások, majd az UWP-platform Minőség kategóriája>: Alacsony minőség kiválasztása. Az Árnyékok tulajdonságot is beállíthatja az Árnyékok letiltása értékre.

Azt javasoljuk, hogy a Unityben használjon sült világítást a modellekkel.

Poliszám csökkentése

A sokszögek száma a következővel csökken:

  1. Objektumok eltávolítása egy jelenetből
  2. Eszköz decimálása, amely csökkenti az adott hálóhoz tartozó sokszögek számát
  3. Részletességi (LOD) rendszer implementálása az alkalmazásba, amely távolról jeleníti meg az azonos geometria alacsonyabb sokszögű verzióját tartalmazó objektumokat

Az árnyékolók ismertetése a Unityben

A teljesítményárnyékolók összehasonlításának egyszerű közelítése az, ha azonosítja az egyes futtatások futásidejében végrehajtott műveletek átlagos számát. Ez könnyen elvégezhető a Unityben.

  1. Válassza ki az árnyékolóeszközt, vagy válasszon ki egy anyagot, majd az ellenőr ablakának jobb felső sarkában válassza a fogaskerék ikont, majd a "Select Shader" (Árnyékoló kiválasztása) elemet.

    Árnyékoló kiválasztása a Unityben

  2. Ha a shader objektum ki van jelölve, válassza a "Kód fordítása és megjelenítése" gombot az inspector ablak alatt

    Shader-kód fordítása a Unityben

  3. Az összeállítás után keresse meg az eredmények statisztikai szakaszát a csúcspont és a képpontárnyékoló különböző műveleteinek számával (Megjegyzés: a képpontárnyékolókat gyakran töredékárnyékolóknak is nevezik)

    Unity Standard Shader-műveletek

Képpontárnyékolók optimalizálása

A fenti módszerrel összeállított statisztikai eredményeket vizsgálva a töredezettség-árnyékoló általában több műveletet hajt végre, mint a csúcspont árnyalata. A töredékárnyékolót, más néven a képpontárnyékolót képpontonként hajtja végre a rendszer a képernyő kimenetén, míg a csúcsárnyékoló csak a képernyőre rajzolt összes háló csúcsonkénti végrehajtása.

Így nem csak a töredékárnyékolók rendelkeznek több utasítással, mint a csúcsok árnyékolói az összes világítási számítás miatt, a töredékárnyékolók szinte mindig nagyobb adathalmazon hajthatók végre. Ha például a képernyő kimenete 2k és 2 ezer között van, akkor a töredékárnyékoló 2 000*2 000 = 4 000 000 alkalommal hajtható végre. Ha két szemet jelenít meg, ez a szám duplázódik, mivel két képernyő van. Ha egy vegyes valóságú alkalmazás több átjárással, teljes képernyős utófeldolgozási effektusokkal vagy több háló ugyanazon képpontra való megjelenítésével rendelkezik, ez a szám jelentősen nő.

Ezért a töredékárnyék-árnyékolóban végzett műveletek számának csökkentése általában sokkal nagyobb teljesítménynövekedést eredményez a csúcspont-árnyékoló optimalizálása során.

Unity Standard shader alternatívák

Ahelyett, hogy fizikailag alapú renderelést (PBR) vagy más kiváló minőségű árnyékolót használnál, nézd meg egy performánsabb és olcsóbb árnyékoló használatát. A Mixed Reality Eszközkészlet biztosítja az MRTK standard árnyékolót, amely vegyes valóságú projektekhez lett optimalizálva.

A Unity emellett a Unity Standard árnyékolóhoz képest gyorsabb, kivilágítatlan, csúcsfényes, diffúz és egyéb egyszerűsített árnyalati lehetőségeket is biztosít. További információt a Beépített árnyékolók használata és teljesítménye című témakörben talál.

Shader előzetes betöltése

Használja a Shader előbetöltését és más trükköket a shader betöltési idejének optimalizálásához. A shader előbetöltése különösen azt jelenti, hogy a futtatókörnyezeti shader fordítása miatt nem jelenik meg találat.

Túllépés korlátozása

A Unityben a Jelenet nézet bal felső sarkában a Rajz mód menü összevonásával és a Overdraw (Overdraw) lehetőség kiválasztásával jelenítheti meg a jelenet túlhúzását.

A túllépés általában az objektumoknak a GPU-ba való elküldése előtt történő selejtezésével oldható meg. A Unity részletesen ismerteti az Occlusion Culling motorhoz való implementálását .

Memóriajavaslatok

A túlzott memóriafoglalási & felszabadítási műveletek kedvezőtlen hatással lehetnek a holografikus alkalmazásra, ami inkonzisztens teljesítményt, lefagyott kereteket és egyéb káros viselkedést eredményezhet. Különösen fontos megérteni a memóriahasználattal kapcsolatos szempontokat a Unity fejlesztése során, mivel a memóriakezelést a szemétgyűjtő szabályozza.

Szemétgyűjtés

A holografikus alkalmazások elveszítik a számítási időt a szemétgyűjtő (GC) számára, amikor a GC aktiválva van az olyan objektumok elemzéséhez, amelyek a végrehajtás során már nem tartoznak hatókörbe, és a memóriájukat ki kell szabadítani, hogy újra felhasználhatók legyenek. Az állandó foglalásokhoz és foglalások megszüntetéséhez általában a szemétgyűjtőnek gyakrabban kell futnia, ami rontja a teljesítményt és a felhasználói élményt.

A Unity egy kiváló oldalt biztosított, amely részletesen ismerteti, hogyan működik a szemétgyűjtő, és tippeket a hatékonyabb kódíráshoz a memóriakezelés terén.

Az egyik leggyakoribb eljárás, amely túlzott szemétgyűjtéshez vezet, nem gyorsítótárazási hivatkozásokat a Unity-fejlesztés összetevőire és osztályaira. A hivatkozásokat a Start() vagy Az ébrenlét() során kell rögzíteni, és később olyan funkciókban kell újra felhasználni, mint az Update() vagy a LateUpdate().

Egyéb gyors tippek:

  • A StringBuilder C# osztály használatával dinamikusan hozhat létre összetett sztringeket futtatókörnyezetben
  • Ha már nincs rájuk szükség, távolítsa el a Debug.Log() hívásait, mivel továbbra is végrehajtják az alkalmazás összes buildverzióját
  • Ha a holografikus alkalmazás általában sok memóriát igényel, fontolja meg a System.GC.Collect() meghívását a betöltési fázisokban, például egy betöltési vagy áttűnési képernyő bemutatásakor

Objektumkészletezés

Az objektumkészletezés népszerű módszer a folyamatos objektumfoglalás és felszabadítások költségének csökkentésére. Ez egy nagy méretű, azonos objektumokból álló készlet lefoglalásával és az inaktív, rendelkezésre álló példányok újbóli használatával történik a készletből, ahelyett, hogy az objektumokat folyamatosan létrehozva és megsemmisítve az idő múlásával. Az objektumkészletek kiválóan használhatók olyan újrafelhasználható összetevőkhöz, amelyek változó élettartammal rendelkeznek egy alkalmazás során.

Indítási teljesítmény

Érdemes lehet kisebb jelenettel elindítani az alkalmazást, majd a SceneManager.LoadSceneAsync használatával betölteni a jelenet többi részét. Ez lehetővé teszi, hogy az alkalmazás a lehető leggyorsabban interaktív állapotba lépjen. Előfordulhat, hogy az új jelenet aktiválása közben nagy cpu-kiugrás tapasztalható, és a renderelt tartalmak akadozhatnak vagy ütközhetnek. Ennek egyik módja, ha az AsyncOperation.allowSceneActivation tulajdonságot "false" értékre állítja a betöltött jeleneten, várja meg, amíg a jelenet betöltődik, törölje a képernyőt feketére, majd állítsa vissza "true" értékre a jelenet aktiválásának befejezéséhez.

Ne feledje, hogy amíg az indítási jelenet be van töltve, a holografikus kezdőképernyő megjelenik a felhasználó számára.

Lásd még