Leistung

Erste Schritte

Die einfachste Möglichkeit, die Leistung zu rationalisieren, ist die Framerate oder wie oft Ihre Anwendung ein Bild pro Sekunde rendern kann. Es ist wichtig, die Zielframerate zu erfüllen, wie von der Zielplattform (z.B. Windows Mixed Reality,Oculususw.) beschrieben. Beispielsweise beträgt HoloLens 60 FPS als Zielframerate. Anwendungen mit niedriger Framerate können zu unerschmierten Benutzererfahrungen führen, z. B. zu einer gespürten Hologramms-Stabilität, Weltverfolgung, Handtracking und mehr. Das Mixed Reality Toolkit bietet eine Vielzahl von Tools und Skripts, um Entwicklern das Nachverfolgen und Erreichen einer qualitativ hochwertigen Framerate zu ermöglichen.

Visueller Profiler

Um die Leistung über die Lebensdauer der Entwicklung kontinuierlich nachverfolgung zu können, wird dringend empfohlen, beim Debuggen einer Anwendung immer ein Visuelles mit & Framerate zu zeigen. Das Mixed Reality Toolkit stellt das Visual Profiler-Diagnosetool bereit, das Echtzeitinformationen zur aktuellen FPS- und Speicherauslastung in der Anwendungsansicht liefert. Der Visual Profiler kann über die Diagnosesystem-Einstellungen unter dem MRTK-Profilinspektor konfiguriert werden.

Darüber hinaus ist es besonders wichtig, den Visual Profiler zum Nachverfolgen der Framerate zu verwenden, wenn er auf dem Gerät ausgeführt wird, anstatt im Unity-Editor oder in einem Emulator auszuführen. Die genauesten Leistungsergebnisse werden dargestellt, wenn auf dem Gerät mit Releasekonfigurations-Builds ausgeführt wird.

Hinweis

Wenn Sie für Windows Mixed Reality erstellen, stellen Sie die Bereitstellung mit MASTER-Konfigurations-Builds vor.

Visual Profiler-Schnittstelle

Optimierungsfenster

Das MRTK-Optimierungsfenster bietet Informationen und Automatisierungstools, mit deren Hilfe Mixed Reality-Entwickler ihre Umgebung für optimale Ergebnisse einrichten und potenzielle Engpässe in ihren Szenenressourcen erkennen können. Bestimmte Schlüsselkonfigurationen in Unity können dabei helfen, wesentlich optimierte Ergebnisse für Mixed Reality-Projekte zu liefern.

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

Die empfohlenen Einstellungen, auf die unten verwiesen wird, können in einem Unity-Projekt mithilfe des MRTK-Optimierungsfensters automatisch konfiguriert werden.

MRTK-Optimierungsfenster Einstellungen

Unity Profiler

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

Zeitaufwand für die CPU

Unity Profiler-Beispiel Graph

Um komfortable Frameraten (in der Regel 60 Frames pro Sekunde) zu erhalten, müssen Anwendungen eine maximale Framezeit von 16,6 Millisekunden CPU-Zeit erreichen. Um die Kosten der MRTK-Funktionalität zu ermitteln, enthält das Microsoft Mixed Reality Toolkit Marker für Codepfade mit innerer Schleife (pro Frame). Diese Marker verwenden das folgende Format, um die spezifische Funktionalität zu verstehen, die verwendet wird:

[MRTK] className.methodName

Hinweis

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

Unity Profiler-Beispielhierarchie

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

Es wird dringend empfohlen, dass Entwickler Anwendungscode auf ähnliche Weise instrumentiert. Der Schwerpunkt der Instrumentierung von Anwendungscode liegt in Ereignishandlern, da diese Methoden der MRTK-Updateschleife in Rechnung gestellt werden, wenn Ereignisse ausgelöst werden. Hohe Framezeiten innerhalb der MRTK-Updateschleife können auf teuren Code in Ereignishandlermethoden hindeken.

Single-Pass Instanzrendering

Die Standardrenderingkonfiguration für XR in Unity ist Multipass. Diese Einstellung weist Unity an, die gesamte Renderpipeline zweimal für jedes Auge auszuführen. Dies kann optimiert werden, indem Sie stattdessen Single Pass Instanced Rendering auswählen. Diese Konfiguration nutzt Renderzielarrays, um einen einzelnen Zeichnen-Aufruf ausführen zu können, der Instanzen in das entsprechende Renderziel für jedes Auge einbetten kann. Darüber hinaus ermöglicht dieser Modus, dass das ganze Rendering in einer einzigen Ausführung der Renderingpipeline erfolgt. Daher kann die Auswahl von Single Pass Instanced Rendering als Renderingpfad für eine Mixed Reality-Anwendung erhebliche Zeit für die CPU-GPU sparen und ist die empfohlene Renderingkonfiguration.

Um jedoch einen einzelnen Zeichnen-Aufruf für jedes Gitter für jedes Auge aus geben zu können, muss die GPU-Instancing von allen Shadern unterstützt werden. Durch die Instancing kann die GPU Multiplex-Zeichnen-Aufrufe über beide Augen hinweg ausführen. Integrierte Unity-Shader sowie der MRTK Standard-Shader enthalten standardmäßig die erforderlichen Anweisungen für die Instancing im Shadercode. Wenn Sie jedoch benutzerdefinierte Shader für Unity schreiben, müssen diese Shader möglicherweise aktualisiert werden, um single pass Instanced-Rendering zu unterstützen.

Beispielcode für benutzerdefinierten 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 bietet Voreinstellungen, 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 Benutzeroberfläche und mehr. Es wird empfohlen, diese Einstellungen zu senken und die Anzahl von Berechnungen zu optimieren, die während des Renderings ausgeführt werden.

Schritt 1: Aktualisieren von Mixed Reality-Unity-Projekten für die Verwendung der Einstellung "Low Quality level"
BearbeitenProject Einstellungen, und wählen Sie dann die Kategorie Qualität Für UWP-Plattform niedrige Qualität auswählen aus.

Schritt 2: Deaktivieren Sie für jede Unity-Szenendatei globale Echtzeit-Benachrichtigungen.
FensterRenderingBeleuchtungs EinstellungenDeaktivieren der Option "Globale Echtzeit-Beleuchtung"

Tiefenpufferfreigabe (HoloLens)

Wenn Sie für die Windows Mixed Reality-Plattform und insbesondere für HoloLens entwickeln, kann die Aktivierung der Tiefenpufferfreigabe unter XR Einstellungen bei der Hologramms-Stabilität 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 eine Genauigkeit von 16 Bit zu konfigurieren.

Wenn Z-Fighting aufgrund des niedrigeren Bitformats auftritt, vergewissern Sie sich, dass die ferne Clipebene aller Kameras auf den geringstmöglichen Wert für die Anwendung festgelegt ist. Unity legt standardmäßig eine ferne Clipebene von 1.000 m fest. Auf HoloLens ist eine weit entfernte Clipebene von 50 m in der Regel für die meisten Anwendungsszenarien mehr als ausreichend.

Hinweis

Bei Verwendung des 16-Bit-Tiefenformatsfunktionieren die erforderlichen Effekte des Schablonenpuffers nicht, da Unity in dieser Einstellung keinen Schablonenpuffer erstellt. Wenn Sie umgekehrt das 24-Bit-Tiefenformat auswählen, wird in der Regel ein 8-Bit-Schablonenpuffer erstellt, falls zutreffend auf der Endpunktgrafikplattform.

Wenn Sie eine Mask-Komponente verwenden, die den Schablonenpuffer erfordert, sollten Sie stattdessen RectMask2D verwenden. Dies erfordert keinen Schablonenpuffer und kann daher in Verbindung mit einem 16-Bit-Tiefenformatverwendet werden.

Hinweis

Um schnell zu bestimmen, welche Objekte in einer Szene nicht visuell in den Tiefenpuffer schreiben, können Sie das Hilfsprogramm Render Depth Buffer unter dem Editor Einstellungen im MRTK-Konfigurationsprofil verwenden.

Optimieren von Meshdaten

Die Einstellungen Für Gitternetzdaten optimieren versuchen, nicht verwendete Scheitelpunktattribute in Ihrer Anwendung zu entfernen. Die Einstellung führt dies durch Ausführen über jeden Shaderpass in jedem Material aus, das sich in jedem Gitter im Build befindet. Dies ist gut für die Größe von Spieldaten und die Laufzeitleistung, kann aber die Buildzeiten erheblich beeinträchtigen.

Es wird empfohlen, diese Einstellung während der Entwicklung zu deaktivieren und während der Erstellung des Master-Build erneut zu aktivieren. Die Einstellung finden Sie unter BearbeitenProject Einstellungen PlayerOther EinstellungenOptimize Mesh Data.

Allgemeine Empfehlungen

Die Leistung kann für Mixed Reality-Entwickler eine mehrdeutige und sich ständig ändernde Herausforderung sein, und das Spektrum an Wissen zur Rationalisierung der Leistung ist sehr groß. Es gibt jedoch einige allgemeine Empfehlungen, um zu verstehen, wie die Leistung für eine Anwendung ansatzt.

Es ist hilfreich, die Ausführung einer Anwendung in die Teile zu vereinfachen, die auf der CPU oder gpu ausgeführt werden, und so zu ermitteln, ob eine App durch eine komponente gebunden ist. Es kann Engpässe geben, die sowohl Verarbeitungseinheiten als auch einige einzigartige Szenarien umfassen, die sorgfältig untersucht werden müssen. Für den Einstieg ist es jedoch gut zu verstehen, wo eine Anwendung für die meiste Zeit ausgeführt wird.

GPU-Begrenzung

Da die meisten Plattformen für Mixed Reality-Anwendungen stereo-rendern, ist es sehr üblich, gpu-gebunden zu sein, da ein "doppelt breiter" Bildschirm gerendert wird. Mobile Mixed Reality-Plattformen wie HoloLens oder Oculus Quest werden außerdem durch CPU-GPU-Verarbeitungsleistung der mobilen Klasse & eingeschränkt.

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

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

Ohne tiefgehende Einblicke in das komplexe Feld der Renderingpipelines für Computergrafiken ist jede Shaderphase ein Programm, das auf der GPU ausgeführt wird, um &&zu erzeugen.

  1. Vertex-Shader transformieren Gitternetzvertices in Koordinaten im Bildschirmbereich (d. h. Code, der pro Scheitelpunkt ausgeführt wird)
  2. Pixel-Shader berechnen die Farbe, die für ein bestimmtes Pixel- und Gitternetzfragment ge zeichnen werden soll (d. h. Code wird pro Pixel ausgeführt).

In Bezug auf die Leistungsoptimierung ist es in der Regel schwieriger, sich auf die Optimierung der Vorgänge im Pixel-Shader zu konzentrieren. Eine Anwendung muss möglicherweise nur einen Cube zeichnen, der nur acht Scheitelsteine enthält. Der Bildschirmraum, den der Cube belegt, liegt jedoch wahrscheinlich in der Reihenfolge von Millionen von Pixeln. Daher kann die Reduzierung von Shadercode um z. B. 10 Vorgänge erheblich mehr Arbeit sparen, wenn der Pixel-Shader reduziert wird als der Vertex-Shader.

Dies ist einer der Hauptgründe für die Nutzung des MRTK-Standard-Shaders, da dieser Shader in der Regel viel weniger Anweisungen pro Pixel-Scheitelpunkt als der Unity Standard-Shader ausgeführt und dabei vergleichbare ergebnisse erzielt.

CPU-Optimierungen GPU-Optimierungen
Logik der App-Simulation Renderingvorgänge
Vereinfachen der Physik Reduzieren von Beleuchtungsberechnungen
Vereinfachen von Animationen Reduzieren der Polygonanzahl & der drawable-Objekte
Verwalten der Garbage Collection Reduzieren der Anzahl von transparenten Objekten
Cacheverweise Vermeiden von Nachverarbeitungs-/Vollbildeffekten

Draw-Aufrufinstancing

Einer der häufigsten Fehler in Unity, der die Leistung verringert, ist das Klonen von Materialien zur Laufzeit. Wenn GameObjects das gleiche Material gemeinsam nutzen und/oder dasselbe Gitternetz sind, können sie mit Techniken wie statische Batchverarbeitung, dynamische Batchverarbeitung und GPU-Instanzion für einzelne Zeichnen-Aufrufe optimiert werden. Wenn Entwickler jedoch eigenschaften des Materials eines Renderers zur Laufzeit ändern, erstellt Unity eine Klonkopie des zugewiesenen Materials.

Wenn z. B. eine Szene 100 Würfel enthält, kann ein Entwickler jeder zur Laufzeit eine eindeutige Farbe zuweisen. Durch den Zugriff auf renderer.material.color in C# erstellt Unity ein neues Material im Arbeitsspeicher für diesen bestimmten Renderer/GameObject. Jeder der 100 Cubes verfügt über ein eigenes Material und kann daher nicht zu einem Zeichnen-Aufruf zusammengeführt werden, sondern zu 100 Draw Call-Anforderungen von der CPU an die GPU.

Um dieses Hindernis zu überwinden und trotzdem eine eindeutige Farbe pro Cube zu zuweisen, 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 hervorragende Leistungstools, die in den Editor integriert sind.

Wenn Sie den ungefähren Leistungsabbruch zwischen einem Shader und einem anderen abschätzen, ist es hilfreich, jeden Shader zu kompilieren und die Anzahl der Vorgänge pro Shaderstufe zu sehen. Wählen Sie hierzu ein Shader-Objekt aus, und klicken Sie auf die Schaltfläche Code kompilieren und anzeigen. Dadurch werden alle Shadervarianten kompiliert und Visual Studio mit den Ergebnissen geöffnet. Hinweis: Die erzeugten Statistikergebnisse können variieren, je nachdem, welche Features für Materialien aktiviert wurden, die den angegebenen Shader verwenden. Unity kompiliert nur die Shadervarianten, die direkt im aktuellen Projekt verwendet werden.

Unity Standard-Shader-Statistikbeispiel

Unity Standard Shader Statistics 1

MRTK Standard-Shaderstatistikbeispiel

MRTK Standard Shader Statistics 2

Weitere Informationen

Unity

Windows Mixed Reality

Oculus

Mesh-Optimierung