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.

A közelmúltban kiadtunk egy Minőségi alapok nevű alkalmazást, amely az 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ölt 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 lásd 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ó. Részletes útmutatást is talál a PIX HoloLens 2 használatához és telepítéséhez. 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ídon való vá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áson belül egy adott keretre vonatkozóan.

    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 az ismétlődő Unity-visszahívásokban, például az Update() műveletben 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, az 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 hí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 egy 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ő modul kezelése>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 megközelítésnek 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 meglévő 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

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 és2) statikusként van 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 nagyszerű 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étrehozza az Anyag másolatát, é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/távoli klipsí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ójában leírt 24 bites mélységi formátum kiválasztásával létrehoz egy 24 bites z-puffert és egy 8 bites rajzsablonpuffert (ha 32 bites alkalmazható egy eszközön (például a HoloLens), ami általában így van).

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 á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 > Válassza a Gyenge minőség lehetőséget. 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 modelljeivel.

A poliek számának 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 egy adott háló sokszögeinek 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 megértése a Unityben

A teljesítményárnyékolók összehasonlításának egyszerű közelítése az egyes futtatások futásidejű végrehajtásának átlagos száma. Ez könnyen elvégezhető a Unityben.

  1. Válassza ki az árnyékoló eszközét 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 lefordított statisztikai eredményeket tekintve a töredékárnyékoló általában több műveletet hajt végre, mint a csúcsárnyékoló. A töredékárnyékolót( más néven képpontárnyékolót) a rendszer képpontonként hajtja végre a képernyő kimenetén, míg a csúcsárnyékoló csak a képernyőre rajzolt összes háló csúcsánként lesz végrehajtva.

Így nem csak a töredékárnyékolóknak van több utasítása, mint a csúcsárnyékolóknak 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 renderel, ez a szám megduplázódik, mivel két képernyő van. Ha egy vegyes valósági alkalmazás több menettel, teljes képernyős utófeldolgozási effektusokkal rendelkezik, vagy több hálót jelenít meg ugyanarra a képpontra, ez a szám jelentősen megnő.

Ezért a töredé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úcsárnyékoló optimalizálásaihoz képest.

A Unity Standard shader alternatívái

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 nagyobb teljesítményű és olcsóbb árnyékoló használatát. A Mixed Reality Eszközkészlet az MRTK standard árnyékolót biztosítja, amely vegyes valósági 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 árnyékolási lehetőségeket is biztosít. Részletesebb információkért lásd: A beépített árnyékolók használata és teljesítménye .

Shader preloading

A Shader előzetes betöltésével és egyéb trükkökkel optimalizálhatja a shader betöltési idejét. 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úlárazás korlátozása

A Unityben a Jelenet nézet bal felső sarkában található Rajzolási mód menüt a Túlhúzás lehetőség kiválasztásával jelenítheti meg.

A túlárazást általában úgy lehet enyhíteni, ha az objektumokat a GPU-ra való küldés előtt idő előtt selejtezi le. 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 káros 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 Unityben való fejlesztéskor, mivel a memóriakezelést a szemétgyűjtő vezérli.

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 már nem tartoznak a hatókörbe a végrehajtás során, és a memóriájukat ki kell szabadítani, hogy újra felhasználhatók legyenek. Az állandó kiosztások és kiosztások általában megkövetelik, hogy a szemétgyűjtő gyakrabban fusson, 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 a szemétgyűjtő működését, és tippeket ad a hatékonyabb kódíráshoz a memóriakezelés terén.

A túlzott szemétgyűjtéshez vezető egyik leggyakoribb eljárás a Unity-fejlesztés összetevőire és osztályaira mutató hivatkozások gyorsítótárazása. A hivatkozásokat a Start() vagy a Awake() során kell rögzíteni, és később olyan függvényekben kell újra felhasználni, mint az Update() vagy a LateUpdate().

További gyors tippek:

  • A StringBuilder C# osztály használatával dinamikusan hozhat létre összetett sztringeket futásidőben
  • Távolítsa el a Debug.Log() hívásait, ha már nincs rá szükség, mivel továbbra is az alkalmazás összes buildverziójában futnak
  • 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ő megjelenítésekor

Objektumkészletezés

Az objektumkészletezés egy népszerű technika a folyamatos objektumfoglalás és felszabadítások költségeinek csökkentésére. Ez egy nagy méretű, azonos objektumokból álló készlet lefoglalásával és a készletből származó inaktív, rendelkezésre álló példányok újrafelhasználásával történik, nem pedig az objektumok folyamatos ívásával és megsemmisítésével. Az objektumkészletek kiválóan használhatók olyan újrafelhasználható összetevőkhöz, amelyek változó élettartammal rendelkeznek az alkalmazások 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 mértékű cpu-kiugrás tapasztalható, és a renderelt tartalmak akadozhatnak vagy akadozhatnak. Ennek egyik módja, ha az AsyncOperation.allowSceneActivation tulajdonságot "false" értékre állítja a betöltött jeleneten, megvárja a jelenet betöltését, törli 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 az indítási jelenet betöltése közben a holografikus kezdőképernyő megjelenik a felhasználó számára.

Lásd még