Leistung – MRTK2

Erste Schritte

Die einfachste Möglichkeit, die Leistung zu rationalisieren, ist über Framerate oder wie oft Ihre Anwendung ein Bild pro Sekunde rendern kann. Es ist wichtig, die Zielframerate zu erfüllen, wie durch die Zielplattform beschrieben (z. B. Windows Mixed Reality, Oculus usw.). Bei HoloLens ist beispielsweise die Zielframerate 60 FPS. Niedrige Framerateanwendungen können zu einer verschlechterten Benutzererfahrung führen, z. B. eine verschlechterte Hologrammstabilisierung, Weltverfolgung, Handverfolgung und vieles mehr. Um Entwicklern dabei zu helfen, die Qualitätsframerate zu verfolgen und zu erreichen, bietet Mixed Reality Toolkit eine Vielzahl von Tools und Skripts.

Visuelles Profiler

Um die Leistung während der Lebensdauer der Entwicklung kontinuierlich zu verfolgen, empfiehlt es sich, während des Debuggens einer Anwendung immer eine Framerate anzuzeigen & . Mixed Reality Toolkit bietet das Visual Profiler-Diagnosetool, das Echtzeitinformationen zur aktuellen FPS- und Speichernutzung in der Anwendungsansicht bietet. Der Visual Profiler kann über die Diagnosesystemeinstellungen unter dem MRTK Profile Inspector konfiguriert werden.

Darüber hinaus ist es besonders wichtig, die Visual Profiler zu verwenden, um Framerate beim Ausführen auf dem Gerät zu verfolgen, 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, um Mixed Reality-Entwickler dabei zu unterstützen, ihre Umgebung für die besten Ergebnisse einzurichten und potenzielle Engpässe in ihren & Szenenressourcen zu identifizieren. 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 eindeutig, dass zwei Bildschirme (d. h. zwei Augen) für die gesamte Szene gerendert werden.

Die unten genannten empfohlenen Einstellungen können in einem Unity-Projekt automatisch konfiguriert werden, indem Sie das MRTK-Optimierungsfenster nutzen.

MRTK-Fenstereinstellungen optimieren

Unity Profiler

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

Auf der CPU ausgegebene Zeit

Beispiel für Unity Profiler Graph

Um komfortable Frameraten zu erhalten (in der Regel 60 Frames pro Sekunde), müssen Anwendungen eine maximale Framezeit von 16,6 Millisekunden der CPU-Zeit erreichen. Um die Kosten der MRTK-Funktionalität zu identifizieren, enthält Microsoft Mixed Reality Toolkit eine Markierung für inneren Schleifenpfade (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 Namen der Methode 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 die Hierarchie des Unity-Profilers

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 verwendet. 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, den Anwendungscode von Entwicklern in ähnlicher Weise zu instrumentieren. Primärer Fokus für Anwendungscodeinstrumentation liegt in Ereignishandlern, da diese Methoden der MRTK-Updateschleife berechnet werden, da Ereignisse ausgelöst werden. Hohe Framezeiten innerhalb der MRTK-Updateschleife können in Ereignishandlermethoden auf kostspieligen Code hinweisen.

Single-Pass Instanzd-Rendering

Die Standard-Renderingkonfiguration für XR in Unity ist Multi-Pass. Diese Einstellung weist Unity an, die gesamte Renderpipeline zweimal auszuführen, einmal für jedes Auge. Dies kann optimiert werden, indem Sie stattdessen das Rendern von Single Pass Instanced auswählen. Diese Konfiguration nutzt Renderzielarrays , um einen einzelnen Zeichnungsaufruf auszuführen, der instanziert wird, um das entsprechende Renderziel für jedes Auge auszuführen. Darüber hinaus ermöglicht dieser Modus, dass das Rendering in einer einzigen Ausführung der Renderingpipeline ausgeführt werden kann. Die Auswahl des Single Pass Instanced Rendering als Renderingpfad für eine Mixed Reality-Anwendung kann daher sowohl auf der CPU-GPU & als auch bei der empfohlenen Renderingkonfiguration erhebliche Zeit sparen.

Um jedoch einen einzelnen Zeichnungsaufruf für jedes Auge zu stellen, muss die GPU-Instance von allen Shadern unterstützt werden. Durch die Instance kann die GPU mehrere 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 von Single Pass Instanced 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, Anti-Aliasing, globale Beleuchtung und vieles mehr. Es wird empfohlen, diese Einstellungen zu verringern und die Anzahl der Berechnungen zu optimieren, die während des Renderings ausgeführt werden.

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

Schritt 2: Deaktivieren Sie für jede Unity-Szenedatei Echtzeit-Globale Beleuchtung
Fenster>Rendering>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 XR-Einstellungen bei der Stabilisierung des Hologramms helfen. Die Verarbeitung des Tiefenpuffers kann jedoch eine Leistungskosten verursachen, insbesondere bei Verwendung des 24-Bit-Tiefenformats. Daher empfiehlt es sich sehr, den Tiefenpuffer auf 16-Bit-Genauigkeit zu konfigurieren.

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

Hinweis

Wenn Sie das 16-Bit-Tiefenformat verwenden, funktioniert der Schablonenpuffer nicht, da Unity keinen Schablonenpuffer in dieser Einstellung erstellt. Bei der Auswahl des 24-Bit-Tiefenformats wird im Allgemeinen ein Schablonenpuffer mit 8 Bit erstellt, falls zutreffend auf der Endpunktgrafikplattform.

Wenn Sie eine Mask-Komponente verwenden, die den Schablonenpuffer erfordert, sollten Sie stattdessen RectMask2D verwenden, was nicht den Schablonenpuffer 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 Rendertiefepuffer-Hilfsprogramm unter den Editoreinstellungen im MRTK-Konfigurationsprofil verwenden.

Optimieren von Gitterdaten

Die Einstellungen "Gitterdaten optimieren " versucht, nicht verwendete Vertexattribute in Ihrer Anwendung zu entfernen. Die Einstellung führt dies durch Ausführen jedes Shaders in jedem Material aus, das sich auf jedem Gitter im Build befindet. Dies ist gut für die Leistung von Spieldaten und die Laufzeit, kann aber die Buildzeiten drastisch beeinträchtigen.

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

Allgemeine Empfehlungen

Die Leistung kann eine mehrdeutige und ständig wechselnde Herausforderung für Mixed Reality-Entwickler sein und das Wissensspektrum, um die Leistung zu rationalisieren, ist enorm. Es gibt 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 so ermitteln, ob eine App von einer Komponente gebunden ist. Es kann Engpässe geben, die sowohl Verarbeitungseinheiten als auch einige eindeutige Szenarien umfassen, die sorgfältig untersucht werden müssen. Bei den ersten Schritten ist es jedoch gut zu verstehen, wo eine Anwendung für die meisten Zeit ausgeführt wird.

GPU gebunden

Da die meisten Plattformen für Mixed Reality-Anwendungen stereoskopische Renderings verwenden, ist es aufgrund der Art des Renderns eines "double-wide" Bildschirms sehr häufig. Futhermore, mobile Mixed Reality-Plattformen wie HoloLens oder Oculus Quest werden durch die CPU-Verarbeitungsleistung & der mobilen Klasse begrenzt.

Wenn Sie sich auf die GPU konzentrieren, gibt es in der Regel zwei wichtige Phasen, die eine Anwendung jeden Frame abschließen muss.

  1. Ausführen des Vertex-Shaders
  2. Führen Sie den Pixel-Shader aus (auch als Fragment-Shader bezeichnet)

Ohne tiefes Tauchen in das komplexe Feld der Computergrafik-Renderingpipelinen& ist jede Shaderstufe ein Programm, das auf der GPU ausgeführt wird, um folgendes zu erzeugen.

  1. Vertex-Shader transformieren Gittervertices in Koordinaten im Bildschirmraum (d. h. Code, der pro Vertex ausgeführt wird)
  2. Pixel-Shader berechnen die Farbe, die für ein bestimmtes Pixel- und Gitterfragment (d. h. Code pro Pixel ausgeführt wird)

Im Hinblick auf die Leistungsoptimierung ist es in der Regel produktiver, sich auf die Optimierung der Vorgänge im Pixel-Shader zu konzentrieren. Eine Anwendung muss möglicherweise nur einen Würfel zeichnen, der nur 8 Scheitelpunkte aufweist. Der Bildschirmraum, den der Würfel besetzt, ist jedoch wahrscheinlich auf 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

Weitere Informationen

Unity

Windows Mixed Reality

Oculus

Gitteroptimierung