Rendimiento: MRTK2

Introducción

La manera más fácil de racionalizar el rendimiento es a través de la velocidad de fotogramas o cuántas veces la aplicación puede representar una imagen por segundo. Es importante cumplir con la velocidad de fotogramas de destino, tal como se describe en la plataforma que se dirige (es decir, Windows Mixed Reality, Escribes, etc.). Por ejemplo, en HoloLens, la velocidad de fotogramas de destino es de 60 FPS. Las aplicaciones de velocidad de fotogramas bajas pueden dar lugar a experiencias de usuario deterioradas, como la estabilización de holograma empeorada, el seguimiento mundial, el seguimiento de manos, etc. Para ayudar a los desarrolladores a realizar un seguimiento y lograr una velocidad de fotogramas de calidad, Mixed Reality Toolkit proporciona una variedad de herramientas y scripts.

Generador de perfiles visuales

Para realizar un seguimiento continuo del rendimiento durante la duración del desarrollo, se recomienda mostrar siempre un objeto visual de velocidad de fotogramas mientras se ejecuta & la depuración de una aplicación. Mixed Reality Toolkit proporciona la herramienta de diagnóstico de Visual Profiler que proporciona información en tiempo real sobre el uso actual de FPS y memoria en la vista de la aplicación. Visual Profiler se puede configurar a través de la configuración del sistema de diagnóstico en el Inspector de perfiles de MRTK.

Además, es especialmente importante usar Visual Profiler para realizar un seguimiento de la velocidad de fotogramas cuando se ejecuta en el dispositivo en lugar de ejecutarse en el editor de Unity o en un emulador. Los resultados de rendimiento más precisos se representarán al ejecutarse en el dispositivo con compilaciones de configuración de versión.

Nota

Si se compila para Windows Mixed Reality, implemente con compilaciones de configuración MASTER.

Interfaz de Visual Profiler

Optimización de la ventana

La ventana Optimización de MRTK ofrece herramientas de automatización e información para ayudar a los desarrolladores de realidad mixta a configurar su entorno para obtener los mejores resultados e identificar posibles cuellos de botella en sus recursos de escena & . Algunas configuraciones clave de Unity pueden ayudar a ofrecer resultados considerablemente más optimizados para proyectos de realidad mixta.

Por lo general, estas opciones implican configuraciones de representación que son ideales para la realidad mixta. Las aplicaciones de realidad mixta son únicas en comparación con el desarrollo tradicional de gráficos 3D en que hay dos pantallas (es decir, dos ojos) para representarse para toda la escena.

Las opciones recomendadas a las que se hace referencia a continuación se pueden configurar automáticamente en un proyecto de Unity aprovechando la ventana Optimización de MRTK.

Configuración de la ventana Optimización de MRTK

Generador de perfiles de Unity

Unity Profiler es una herramienta útil para investigar los detalles del rendimiento de la aplicación en un nivel de fotograma a fotograma.

Tiempo invertido en la CPU

Gráfico de generador de perfiles de Unity de ejemplo

Para mantener velocidades de fotogramas cómodas (normalmente 60 fotogramas por segundo), las aplicaciones deben lograr un tiempo máximo de período de 16,6 milisegundos de tiempo de CPU. Para ayudar a identificar el costo de la funcionalidad de MRTK, Microsoft Mixed Reality Toolkit contiene marcadores para rutas de código de bucle interno (por fotograma). Estos marcadores usan el siguiente formato para ayudar a comprender la funcionalidad específica que se utiliza:

[MRTK] className.methodName

Nota

Puede haber datos adicionales después del nombre del método. Esto se usa para identificar funcionalidades potencialmente costosas ejecutadas condicionalmente que pueden evitarse mediante pequeños cambios en el código de la aplicación.

Jerarquía de Generador de perfiles de Unity de ejemplo

En este ejemplo, la jerarquía se ha expandido para mostrar que el método UpdateHandData de la clase WindowsMixedRealityArticulatedHand consume 0,44 ms de tiempo de CPU durante el marco que se analiza. Estos datos se pueden usar para ayudar a determinar si un problema de rendimiento está relacionado con el código de la aplicación o desde otro lugar del sistema.

Se recomienda encarecidamente que los desarrolladores instrumentan el código de aplicación de forma similar. Las áreas principales de enfoque para la instrumentación de código de aplicación están dentro de los controladores de eventos, ya que estos métodos se cobran al bucle de actualización de MRTK a medida que se generan eventos. Los tiempos de fotogramas elevados dentro del bucle de actualización de MRTK pueden ser indicativos de código costoso en los métodos del controlador de eventos.

representación de instancia de Single-Pass

La configuración de representación predeterminada para XR en Unity es Multi-pass. Esta configuración indica a Unity que ejecute la canalización de representación completa dos veces, una vez para cada ojo. Esto se puede optimizar seleccionando representación de instancia de paso único en su lugar. Esta configuración aprovecha las matrices de destino de representación para poder realizar una sola llamada de dibujo que las instancias en el destino de representación adecuado para cada ojo. Además, este modo permite realizar toda la representación en una sola ejecución de la canalización de representación. Por lo tanto, la selección de representación de instancia de paso único como ruta de representación para una aplicación de realidad mixta puede ahorrar mucho tiempo en la GPU de CPU & y es la configuración de representación recomendada.

Sin embargo, para emitir una sola llamada de dibujo para cada malla a cada ojo, todas las sombreadores deben admitir la creación de instancias de GPU . La creación de instancias permite que la GPU dibuje las llamadas a través de ambos ojos. Los sombreadores integrados de Unity, así como el sombreador ESTÁNDAR de MRTK , contienen de forma predeterminada las instrucciones de creación de instancias necesarias en el código del sombreador. Si escribe sombreadores personalizados aunque para Unity, es posible que sea necesario actualizar estos sombreadores para admitir la representación de instancias de paso único.

Código de ejemplo para el sombreador personalizado

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

Configuración de calidad

Unity proporciona valores preestablecidos para controlar la calidad de la representación para cada punto de conexión de la plataforma. Estos valores preestablecidos controlan qué características gráficas se pueden habilitar, como sombras, suavizado de alias, iluminación global, etc. Se recomienda reducir esta configuración y optimizar el número de cálculos realizados durante la representación.

Paso 1: Actualización de proyectos de Unity de realidad mixta para usar la configuración de nivel de baja calidad
Editar>Configuración del proyecto y, a continuación, selecciona la categoría >Calidad Seleccionar baja calidad para la plataforma para UWP.

Paso 2: Para cada archivo de escena de Unity, deshabilite la iluminación global en tiempo real.
Ventana>Renderización>Configuración de> iluminación Desactivación de la iluminación global en tiempo real

Uso compartido del búfer de profundidad (HoloLens)

Si desarrolla para la plataforma de Windows Mixed Reality y, en particular, HoloLens, habilitar el uso compartido de búferes de profundidad en configuración de XR puede ayudar con la estabilización del holograma. Sin embargo, el procesamiento del búfer de profundidad puede suponer un costo de rendimiento, especialmente si se usa el formato de profundidad de 24 bits. Por lo tanto, se recomienda configurar el búfer de profundidad en precisión de 16 bits.

Si se produce z-fighting debido al formato de bits inferior, confirme que el plano de recorte lejano de todas las cámaras está establecido en el valor más bajo posible para la aplicación. Unity establece de forma predeterminada un plano de clip lejano de 1000m. En HoloLens, un plano de clip lejano de 50 m suele ser más que suficiente para la mayoría de los escenarios de la aplicación.

Nota

Si usa el formato de profundidad de 16 bits, los efectos necesarios del búfer de galería de símbolos no funcionarán porque Unity no crea un búfer de galería de símbolos en esta configuración. Al seleccionar el formato de profundidad de 24 bits , por el contrario, se creará un búfer de galería de símbolos de 8 bits, si procede en la plataforma de gráficos de punto de conexión.

Si usa un componente Mask que requiere el búfer de galería de símbolos, considere la posibilidad de usar RectMask2D en su lugar, que no requiere el búfer de galería de símbolos y, por tanto, se puede usar junto con un formato de profundidad de 16 bits.

Nota

Para determinar rápidamente qué objetos de una escena no escriben en el búfer de profundidad visualmente, se puede usar la utilidad Búfer de profundidad de representación en la configuración del editor en el perfil de configuración de MRTK.

Optimización de datos de malla

La configuración Optimizar datos de malla intenta quitar atributos de vértice sin usar dentro de la aplicación. La configuración realiza esta operación mediante la ejecución de cada sombreador que pase cada material que se encuentra en cada malla de la compilación. Esto es bueno para el tamaño de los datos del juego y el rendimiento en tiempo de ejecución, pero puede dificultar drásticamente los tiempos de compilación.

Se recomienda deshabilitar esta configuración durante el desarrollo y volver a habilitarla durante la creación de la compilación "Maestra". La configuración se puede encontrar en Editar>configuración del> proyectoReproductor>Otras configuraciones>Optimizar datos de malla.

Recomendaciones generales

El rendimiento puede ser un desafío ambiguo y constantemente cambiante para los desarrolladores de realidad mixta y el espectro de conocimientos para racionalizar el rendimiento es enorme. Sin embargo, hay algunas recomendaciones generales para comprender cómo abordar el rendimiento de una aplicación.

Resulta útil simplificar la ejecución de una aplicación en las partes que se ejecutan en la CPU o la GPU y, por tanto, identificar si una aplicación está limitada por cualquiera de los componentes. Puede haber cuellos de botella que abarcan las unidades de procesamiento y algunos escenarios únicos que deben investigarse cuidadosamente. Sin embargo, para empezar, es bueno comprender dónde se ejecuta una aplicación durante la mayor cantidad de tiempo.

Con límite de GPU

Dado que la mayoría de las plataformas para aplicaciones de realidad mixta usan la representación estereoscópica, es muy común estar limitado por GPU debido a la naturaleza de representar una pantalla "doble de ancho". Además, las plataformas móviles de realidad mixta, como HoloLens o La misión DeLens, estarán limitadas por la potencia de procesamiento de GPU de CPU & de clase móvil.

Al centrarse en la GPU, generalmente hay dos fases importantes que una aplicación debe completar cada fotograma.

  1. Ejecutar el sombreador de vértices
  2. Ejecutar el sombreador de píxeles (también conocido como sombreador de fragmentos)

Sin profundizar en el campo complejo de canalizaciones de representación de gráficos& de equipos, cada fase del sombreador es un programa que se ejecuta en la GPU para producir lo siguiente.

  1. Los sombreadores de vértices transforman vértices de malla en coordenadas en el espacio de pantalla (es decir, código ejecutado por vértice)
  2. Los sombreadores de píxeles calculan el color que se va a dibujar para un fragmento de píxel y malla determinado (es decir, el código se ejecuta por píxel)

En lo que respecta al ajuste del rendimiento, suele ser más fructífero centrarse en optimizar las operaciones en el sombreador de píxeles. Es posible que una aplicación solo necesite dibujar un cubo que solo tenga 8 vértices. Sin embargo, es probable que el espacio de pantalla que ocupa el cubo esté en el orden de millones de píxeles. Por lo tanto, reducir el código del sombreador por ejemplo, 10 operaciones puede ahorrar mucho más trabajo si se reduce en el sombreador de píxeles que el sombreador de vértices.

Esta es una de las principales razones para aprovechar el sombreador MRTK Standard , ya que este sombreador generalmente ejecuta muchas menos instrucciones por vértice de píxeles & que el sombreador estándar de Unity al lograr resultados estéticos comparables.

Optimizaciones de CPU Optimizaciones de GPU
Lógica de simulación de aplicación Operaciones de representación
Simplificación de la física Reducir los cálculos de iluminación
Simplificar animaciones Reducción del número de recuento & de polígonos de objetos dibujables
Administrar recolección de elementos no utilizados Reducir el número de objetos transparentes
Referencias de caché Evitar efectos posteriores al procesamiento o pantalla completa

Creación de instancias de llamadas de dibujo

Uno de los errores más comunes en Unity que reduce el rendimiento es clonar materiales en tiempo de ejecución. Si GameObjects comparte el mismo material y/o son la misma malla, se pueden optimizar en llamadas de dibujo único a través de técnicas como el procesamiento por lotes estáticos, el procesamiento por lotes dinámicos y las instancias de GPU. Sin embargo, si el desarrollador modifica las propiedades del material de un representador en tiempo de ejecución, Unity creará una copia clonada del material asignado.

Por ejemplo, si hay 100 cubos en una escena, es posible que un desarrollador quiera asignar un color único a cada uno en tiempo de ejecución. El acceso de renderer.material.color en C# hará que Unity cree un nuevo material en memoria para este representador o GameObject determinado. Cada uno de los 100 cubos tendrá su propio material y, por tanto, no se pueden combinar en una llamada de dibujo, sino que, en su lugar, se convertirá en 100 solicitudes de llamada de dibujo de la CPU a la GPU.

Para superar este obstáculo y seguir asignando un color único por cubo, los desarrolladores deben aprovechar MaterialPropertyBlock.

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

Herramientas de rendimiento de Unity

Unity proporciona excelentes herramientas de rendimiento integradas en el editor.

Si se calcula el equilibrio de rendimiento aproximado entre un sombreador y otro, resulta útil compilar cada sombreador y ver el número de operaciones por fase del sombreador. Para ello, seleccione un recurso de sombreador y haga clic en el botón Compilar y mostrar código . Esto compilará todas las variantes del sombreador y abrirá Visual Studio con los resultados. Nota: Los resultados estadísticos producidos pueden variar en función de las características que se han habilitado en los materiales que usan el sombreador determinado. Unity solo compilará las variantes del sombreador que se usan directamente en el proyecto actual.

Ejemplo de estadísticas de sombreador estándar de Unity

Estadísticas de sombreador estándar de Unity 1

Ejemplo de estadísticas de sombreador estándar de MRTK

Estadísticas de sombreador estándar de MRTK 2

Vea también

Unity

Windows Mixed Reality

Oculus

Optimización de malla