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, como se describe en la plataforma dirigida (es decir, Windows Mixed Reality, Agregando, 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 hologramas empeoradas, 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 & depurar 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 información y automatizació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 su escena & recursos. 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 de gráficos 3D tradicionales en que hay dos pantallas (es decir, dos ojos) para representar 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 de optimización de MRTK.

Configuración de la ventana optimizar 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 fotograma cómodas (normalmente 60 fotogramas por segundo), las aplicaciones deben lograr un tiempo de fotograma máximo 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 la funcionalidad ejecutada condicionalmente, potencialmente costosa que pueden evitarse mediante pequeños cambios en el código de la aplicación.

Jerarquía del 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 fotograma que se está analizando. 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 se encuentran dentro de los controladores de eventos, ya que estos métodos se cobran al bucle de actualización mrTK a medida que se generan eventos. Los tiempos de fotograma 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 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 única llamada a draw 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 acceso de representación para una aplicación de realidad mixta puede ahorrar mucho tiempo en la CPU & GPU 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 llamadas de multiplex en 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 estos sombreadores deban actualizarse para admitir la representación de instancias de paso único.

Código de ejemplo para 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 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, seleccione la categoría >Calidad Seleccionar baja calidad para la plataforma de UWP.

Paso 2: Para cada archivo de escena de Unity, deshabilite la iluminación global en tiempo real.
Ventana>Representación>Configuración de> iluminaciónDesactivació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 la 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 encarecidamente 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 1000 m. En HoloLens, un plano de recorte lejano de 50 m suele ser más que suficiente para la mayoría de los escenarios de 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, 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 esto ejecutando cada paso de sombreador en 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>reproductor>de configuración> del proyectoOtras 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 conocimiento 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 e identificar así 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.

Delimitado por 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 limitada por GPU debido a la naturaleza de representar una pantalla "de doble ancho". Además, las plataformas de realidad mixta móvil, como HoloLensos o o Búsqueda, estarán limitadas por la CPU de clase móvil & potencia de procesamiento de GPU.

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 complejo campo de gráficos informáticos & canalizaciones de representación, cada fase del sombreador es un programa que se ejecuta en la GPU para generar lo siguiente.

  1. Los sombreadores de vértices transforman los 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 píxel & vértice que el sombreador estándar de Unity mientras logra 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 Reducir el recuento de polígonos & número 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

Consulte también

Unity

Windows Mixed Reality

Oculus

Optimización de malla