Leistung — MRTK2

Erste Schritte

Die einfachste Möglichkeit zur Rationalisierung der Leistung erfolgt über framerate oder wie oft Ihre Anwendung ein Bild pro Sekunde rendern kann. Es ist wichtig, die Zielframerate zu erfüllen, wie von der Plattform beschrieben, die gezielt ist (z. B. Windows Mixed Reality, Oculus usw.). Bei HoloLens ist beispielsweise die Zielframerate 60 FPS. Anwendungen mit niedriger Framerate können zu verschlechterten Benutzeroberflächen führen, z. B. verschlechterte Hologrammstabilisierung, Weltverfolgung, Handverfolgung und vieles mehr. Um Entwicklern das Nachverfolgen und Erreichen der Qualitätsframerate zu erleichtern, bietet Mixed Reality Toolkit eine Vielzahl von Tools und Skripts.

Visuelles Profiler

Um die Leistung während der Lebensdauer der Entwicklung kontinuierlich nachzuverfolgen, empfiehlt es sich dringend, beim Debuggen einer Anwendung immer eine Framerate visuell & anzuzeigen. Mixed Reality Toolkit stellt das Visual Profiler-Diagnosetool bereit, das Echtzeitinformationen zur aktuellen FPS- und Speichernutzung in der Anwendungsansicht bereitstellt. Der Visuelle Profiler kann über die Diagnosesystemeinstellungen unter dem MRTK Profile Inspector konfiguriert werden.

Darüber hinaus ist es besonders wichtig, den Visual Profiler zu verwenden, um framerate zu verfolgen, wenn es auf dem Gerät ausgeführt wird, anstatt im Unity-Editor oder einem Emulator auszuführen. Die genauesten Leistungsergebnisse werden beim Ausführen auf dem Gerät mit Release-Konfigurationsbuilds dargestellt.

Hinweis

Wenn Sie für Windows Mixed Reality erstellen, stellen Sie mit MASTER-Konfigurationsbuilds bereit.

Visual Profiler-Schnittstelle

Optimierungsfenster

Das MRTK-Optimierungsfenster bietet Informationen und Automatisierungstools, mit denen Mixed Reality-Entwickler ihre Umgebung für die besten Ergebnisse einrichten und potenzielle Engpässe in ihren Szenenressourcen & identifizieren können. Bestimmte Schlüsselkonfigurationen in Unity können wesentlich optimierte Ergebnisse für Mixed Reality-Projekte liefern.

Im Allgemeinen umfassen diese Einstellungen Renderingkonfigurationen, die ideal für Mixed Reality sind. Mixed Reality-Anwendungen sind im Vergleich zur herkömmlichen 3D-Grafikentwicklung einzigartig, da es zwei Bildschirme (d. h. zwei Augen) gibt, die für die gesamte Szene gerendert werden.

Die unten aufgeführten empfohlenen Einstellungen können in einem Unity-Projekt automatisch konfiguriert werden, indem das MRTK-Optimierungsfenster verwendet wird.

MRTK-Fenstereinstellungen optimieren

Unity Profiler

Der Unity Profiler ist ein nützliches Tool, um Details der Anwendungsleistung auf Frame-by-Frame-Ebene zu untersuchen.

Zeitaufwand für die CPU

Beispiel für Unity Profiler Graph

Um komfortable Frameraten (in der Regel 60 Frames pro Sekunde) aufrechtzuerhalten, müssen Anwendungen eine maximale Framezeit von 16,6 Millisekunden cpu-Zeit erreichen. Um die Kosten der MRTK-Funktionalität zu identifizieren, enthält das Microsoft Mixed Reality Toolkit eine Markierung für inneren Schleifencodepfade (pro Frame). Diese Markierungen verwenden das folgende Format, um zu helfen, die spezifische Funktionalität zu verstehen, die verwendet wird:

[MRTK] className.methodName

Hinweis

Es kann zusätzliche Daten geben, die dem Methodennamen folgen. Dies wird verwendet, um bedingt ausgeführte, potenziell teure Funktionen zu identifizieren, die durch kleine Änderungen an Anwendungscode vermieden werden können.

Beispiel für Unity Profiler-Hierarchie

In diesem Beispiel wurde die Hierarchie erweitert, um anzuzeigen, dass die UpdateHandData-Methode der WindowsMixedRealityArticulatedHand-Klasse 0,44 ms CPU-Zeit während der Analyse des Frames verbraucht. Diese Daten können verwendet werden, um zu ermitteln, ob ein Leistungsproblem mit Anwendungscode oder von einer anderen Stelle im System verbunden ist.

Es wird dringend empfohlen, dass Entwickler Anwendungscode auf ähnliche Weise instrumentieren. Primärer Fokusbereich für die Anwendungscodeinstrumentation liegt in Ereignishandlern, da diese Methoden der MRTK-Updateschleife berechnet werden, wenn Ereignisse ausgelöst werden. Hohe Framezeiten innerhalb der MRTK-Updateschleife können in Ereignishandlermethoden auf kostspieligen Code hinweisen.

Single-Pass Instanzdrendering

Die Standardrenderingkonfiguration für XR in Unity ist Multi-Pass. Diese Einstellung weist Unity an, die gesamte Renderpipeline zweimal für jedes Auge auszuführen. Dies kann optimiert werden, indem Sie stattdessen das Rendern einzelner Passinstanzen auswählen. Diese Konfiguration nutzt Renderzielarrays , um einen einzelnen Zeichnungsaufruf ausführen zu können, der Instanzen in das entsprechende Renderziel für jedes Auge eingibt. Darüber hinaus ermöglicht dieser Modus, dass alle Renderings in einer einzigen Ausführung der Renderingpipeline ausgeführt werden. Daher kann die Auswahl des Renderingpfads für single Pass Instanced als Renderingpfad für eine Mixed Reality-Anwendung sowohl auf der CPU-GPU & als auch bei der empfohlenen Renderingkonfiguration erhebliche Zeit sparen.

Um jedoch einen einzelnen Draw-Aufruf für jedes Gitter für jedes Auge auszustellen, muss die GPU-Instance von allen Shadern unterstützt werden. Durch die Instance kann die GPU multiplex-Aufrufe über beide Augen zeichnen. Unity integrierte Shader sowie der MRTK Standard-Shader enthalten standardmäßig die erforderlichen Instanceanweisungen im Shadercode. Wenn benutzerdefinierte Shader für Unity geschrieben werden, müssen diese Shader möglicherweise aktualisiert werden, um das Rendern einzelner Passinstanzen zu unterstützen.

Beispielcode für benutzerdefinierte Shader

struct appdata
{
    float4 vertex : POSITION;
    float2 uv : TEXCOORD0;

    UNITY_VERTEX_INPUT_INSTANCE_ID //Insert
};

struct v2f
{
    float2 uv : TEXCOORD0;
    float4 vertex : SV_POSITION;

    UNITY_VERTEX_OUTPUT_STEREO //Insert
};

v2f vert (appdata v)
{
    v2f o;

    UNITY_SETUP_INSTANCE_ID(v); //Insert
    UNITY_INITIALIZE_OUTPUT(v2f, o); //Insert
    UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o); //Insert

    o.vertex = UnityObjectToClipPos(v.vertex);

    o.uv = v.uv;

    return o;
}

Qualitätseinstellungen

Unity stellt Voreinstellungen bereit, um die Qualität des Renderings für jeden Plattformendpunkt zu steuern. Diese Voreinstellungen steuern, welche grafischen Features aktiviert werden können, z. B. Schatten, Antialiasing, globale Beleuchtung und vieles mehr. Es wird empfohlen, diese Einstellungen zu verringern und die Anzahl der Berechnungen zu optimieren, die während des Renderns ausgeführt werden.

Schritt 1: Aktualisieren von Mixed Reality Unity-Projekten zur Verwendung der Einstellung "Niedrige Qualität "
Redigieren>Projekteinstellungen, und wählen Sie dann die Kategorie >"Qualität" für die UWP-Plattform aus.

Schritt 2: Deaktivieren Sie für jede Unity-Szenendatei die globale Beleuchtung in Echtzeit.
Fenster>Wiedergabe>Beleuchtungseinstellungen>Deaktivieren der globalen Beleuchtung in Echtzeit

Tiefenpufferfreigabe (HoloLens)

Wenn sie für die Windows Mixed Reality-Plattform und insbesondere HoloLens entwickelt werden, kann die Aktivierung der Tiefenpufferfreigabe unter den XR-Einstellungen bei der Stabilisierung des Hologramms helfen. Die Verarbeitung des Tiefenpuffers kann jedoch zu Leistungskosten führen, insbesondere bei Verwendung des 24-Bit-Tiefenformats. Daher wird dringend empfohlen , den Tiefenpuffer auf 16-Bit-Genauigkeit zu konfigurieren.

Wenn z-Kampf aufgrund des niedrigeren Bitformats auftritt, bestätigen Sie, dass die Weitausschnittebene aller Kameras auf den niedrigsten möglichen Wert für die Anwendung festgelegt ist. Unity legt standardmäßig ein weit entferntes Clip-Flugzeug von 1000m fest. Bei HoloLens ist ein weit entfernter Clip-Ebene von 50m im Allgemeinen mehr als genug für die meisten Anwendungsszenarien.

Hinweis

Wenn Sie das 16-Bit-Tiefenformat verwenden, funktioniert der erforderliche Schablonenpuffer nicht, da Unity in dieser Einstellung keinen Schablonenpuffer erstellt . Wenn Sie das 24-Bit-Tiefenformat umgekehrt auswählen, wird in der Regel ein 8-Bit-Schablonenpuffer erstellt, sofern zutreffend auf der Endpunktgrafikplattform.

Wenn Sie eine Mask-Komponente verwenden, die den Schablonenpuffer erfordert, sollten Sie stattdessen RectMask2D verwenden, was den Schablonenpuffer nicht erfordert und somit in Verbindung mit einem 16-Bit-Tiefenformat verwendet werden kann.

Hinweis

Um schnell zu bestimmen, welche Objekte in einer Szene nicht visuell in den Tiefenpuffer geschrieben werden, kann man das Hilfsprogramm "Rendertiefepuffer" unter den Editoreinstellungen im MRTK-Konfigurationsprofil verwenden.

Optimieren von Gitterdaten

Die Einstellungen "Optimieren von Gitterdaten " versuchen, nicht verwendete Vertexattribute in Ihrer Anwendung zu entfernen. Die Einstellung führt dies durch Ausführen aller Shaderdurchlaufe in jedem Material aus, das sich auf jedem Gitter im Build befindet. Dies eignet sich gut für die Größe und Laufzeitleistung von Spielen, kann aber die Buildzeiten drastisch behindern.

Es wird empfohlen, diese Einstellung während der Entwicklung zu deaktivieren und während der Erstellung von "Master"-Builds erneut zu aktivieren. Die Einstellung finden Sie unter "Project>Settings>Player>Andere Einstellungen>Optimieren von Gitterdaten".

Allgemeine Empfehlungen

Die Leistung kann eine mehrdeutige und ständig wechselnde Herausforderung für Mixed Reality-Entwickler sein und das Spektrum der Wissen zur Rationalisierung der Leistung ist enorm. Es gibt jedoch einige allgemeine Empfehlungen zum Verständnis der Leistung für eine Anwendung.

Es ist nützlich, die Ausführung einer Anwendung in die Teile zu vereinfachen, die auf der CPU oder der GPU ausgeführt werden, und identifizieren Sie somit, ob eine App von beiden Komponenten gebunden ist. Es können Engpässe bestehen, die sowohl Verarbeitungseinheiten als auch einige einzigartige Szenarien umfassen, die sorgfältig untersucht werden müssen. Für die ersten Schritte ist es jedoch ratsam, zu erfassen, wo eine Anwendung für die meiste Zeit ausgeführt wird.

GPU gebunden

Da die meisten Plattformen für Mixed Reality-Anwendungen stereoskopisches Rendering verwenden, ist es aufgrund der Art des Renderns eines "double-wide"-Bildschirms sehr üblich. Futhermore, mobile Mixed Reality-Plattformen wie HoloLens oder Oculus Quest werden durch die CPU-Prozessorverarbeitungsleistung & der mobilen Klasse eingeschränkt.

Beim Fokus auf die GPU gibt es in der Regel zwei wichtige Phasen, die eine Anwendung jeden Frame abschließen muss.

  1. Ausführen des Vertex-Shaders
  2. Ausführen des Pixelshaders (auch als Fragment-Shader bezeichnet)

Ohne tief in das komplexe Feld der Computergrafik-Renderingpipelinen& einzutauchen, ist jede Shaderphase ein Programm, das auf der GPU ausgeführt wird, um Folgendes zu erzeugen.

  1. Vertex-Shader transformieren Gittervertices in Koordinaten im Bildschirmbereich (z. B. Code pro Vertex)
  2. Pixel-Shader berechnen die Farbe, die für ein bestimmtes Pixel- und Gitterfragment gezeichnet werden soll (z. B. Code pro Pixel)

Im Hinblick auf die Leistungsoptimierung ist es in der Regel fruchtbarer, sich auf die Optimierung der Vorgänge im Pixelshader zu konzentrieren. Eine Anwendung muss möglicherweise nur einen Würfel zeichnen, der nur 8 Scheitelpunkte aufweist. Der Bildschirmbereich, den der Cube belegt, befindet sich jedoch wahrscheinlich in der Reihenfolge von Millionen von Pixeln. Dadurch kann das Reduzieren des Shadercodes durch 10 Vorgänge erheblich mehr Arbeit sparen, wenn der Pixel-Shader reduziert wird als der Vertex-Shader.

Dies ist eine der wichtigsten Gründe für die Verwendung des MRTK-Standard-Shaders , da dieser Shader im Allgemeinen viele weniger Anweisungen pro & Pixelvertex ausführt als der Unity Standard-Shader, während vergleichbare ästhetische Ergebnisse erzielt werden.

CPU-Optimierungen GPU-Optimierungen
App-Simulationslogik Rendervorgänge
Vereinfachen der Physik Reduzieren von Beleuchtungsberechnungen
Vereinfachen von Animationen Reduzieren der Polygonanzahl & # von zeichnenden Objekten
Verwalten der Garbage Collection Reduzieren von #von transparenten Objekten
Cacheverweise Vermeiden von Nachverarbeitungs-/Vollbildeffekten

Zeichnen von Anrufinstancen

Eine der häufigsten Fehler in Unity, die die Leistung reduziert, ist das Klonen von Materialien zur Laufzeit. Wenn GameObjects das gleiche Material und/oder das gleiche Gitter teilen, können sie über Techniken wie statische Batcherstellung, dynamische Batcherstellung und GPU-Instancing in einzelnen Zeichnungsaufrufen optimiert werden. Wenn entwickler jedoch die Eigenschaften des Materials eines Renderers zur Laufzeit ändern, erstellt Unity eine Klonkopie des zugewiesenen Materials.

Wenn beispielsweise 100 Würfel in einer Szene vorhanden sind, kann ein Entwickler eine eindeutige Farbe jeder zur Laufzeit zuweisen. Der Zugriff auf renderer.material.color in C# macht Unity ein neues Material im Arbeitsspeicher für diesen bestimmten Renderer/GameObject. Jede der 100 Würfel verfügt über ein eigenes Material und kann daher nicht in einen Zeichnungsaufruf zusammengeführt werden, sondern 100 Zeichenanrufanforderungen von der CPU bis zur GPU werden.

Um dieses Hindernis zu überwinden und immer noch eine eindeutige Farbe pro Cube zuzuweisen, sollten Entwickler MaterialPropertyBlock nutzen.

private PropertyBlock m_PropertyBlock ;
private Renderer myRenderer;

private void Start()
{
     myRenderer = GetComponent<Renderer>();
     m_PropertyBlock = new MaterialPropertyBlock();
}

private void ChangeColor()
{
    // Creates a copy of the material once for this renderer
    myRenderer.material.color = Color.red;

    // vs.

    // Retains instancing capability for renderer
    m_PropertyBlock.SetColor("_Color", Color.red);
    myRenderer.SetPropertyBlock(m_PropertyBlock);
}

Unity-Leistungstools

Unity bietet großartige Leistungstools, die in den Editor integriert sind.

Wenn sie den groben Leistungsabbruch zwischen einem Shader und einem anderen schätzen, ist es nützlich, jeden Shader zu kompilieren und die Anzahl der Vorgänge pro Shaderstufe anzuzeigen. Dies kann erfolgen, indem Sie ein Shaderobjekt auswählen und auf die Schaltfläche " Kompilieren" und "Code anzeigen " klicken. Dadurch werden alle Shadervarianten kompiliert und visual studio mit den Ergebnissen geöffnet. Hinweis: Die erstellten Statistikergebnisse variieren je nach aktivierten Features auf Materialien, die den angegebenen Shader verwenden. Unity kompiliert nur die Shadervarianten, die direkt im aktuellen Projekt verwendet werden.

Beispiel für Unity Standard-Shaderstatistiken

Unity Standard-Shaderstatistiken 1

Beispiel für MRTK Standard-Shaderstatistiken

MRTK Standard-Shaderstatistiken 2

Siehe auch

Unity

Windows Mixed Reality

Oculus

Gitteroptimierung