Compartir a través de


Rendimiento: MRTK2

Introducción

La manera más fácil de racionalizar el rendimiento es a través de la velocidad de fotogramas o el número de veces que la aplicación puede representar una imagen por segundo. Es importante cumplir la velocidad de fotogramas de destino, como se describe en la plataforma de destino (es decir, Windows Mixed Reality, Oculus, etc.). Por ejemplo, en HoloLens, la velocidad de fotogramas de destino es de 60 FPS. Las aplicaciones con baja velocidad de fotogramas pueden dar lugar a experiencias de usuario deterioradas, como la estabilización de hologramas empeorada, el seguimiento mundial, el seguimiento de manos y mucho más. 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 mostrarán al ejecutarse en el dispositivo con compilaciones de configuración de versión.

Nota:

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

Interfaz de Visual Profiler

Ventana Optimizar

MrTK Optimize Window 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 sustancialmente más optimizados para proyectos de realidad mixta.

Por lo general, estas configuraciones 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 tradicional, ya que hay dos pantallas (es decir, dos ojos) que se representan para toda la escena.

La configuración recomendada a la que se hace referencia a continuación se puede configurar automáticamente en un proyecto de Unity aprovechando la ventana de optimización de MRTK.

MRTK Optimize Window Settings

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

Ejemplo de gráfico del generador de perfiles de Unity

Para mantener velocidades de fotogramas 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 un marcador para rutas de acceso de código de bucle interno (por fotograma). Estos marcadores usan el siguiente formato para ayudar a comprender la funcionalidad específica que se usa:

[MRTK] className.methodName

Nota:

Puede haber datos adicionales siguiendo el nombre del método. Esto se usa para identificar una funcionalidad potencialmente costosa y ejecutada condicionalmente que se puede evitar 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 instrumente el código de la 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 MRTK a medida que se generan eventos. Los tiempos de fotogramas elevados dentro del bucle de actualización de MRTK pueden indicar código costoso en los métodos del controlador de eventos.

Single-Pass representación con instancias

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 la representación instanciada de paso único en su lugar. Esta configuración aprovecha las matrices de destino de representación para poder realizar una única llamada de dibujo que las instancias en el destino de representación adecuado para cada ojo. Además, este modo permite que toda la representación se realice en una sola ejecución de la canalización de representación. Por lo tanto, la selección de la representación de instancias de paso único como la ruta de representación de 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 única llamada de dibujo para cada malla a cada ojo, todos los sombreadores deben admitir la creación de instancias de GPU . La creación de instancias permite que la GPU dibuje varias llamadas a través de ambos ojos. Los sombreadores integrados de Unity, así como mrtk Standard sombreador de forma predeterminada contienen las instrucciones de creación de instancias necesarias en el código del sombreador. Si escribe sombreadores personalizados 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 de 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 Seleccione 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ónDesactivar iluminación global en tiempo real

Uso compartido del búfer de profundidad (HoloLens)

Si se desarrolla para la plataforma 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 encarecidamente configurar el búfer de profundidad para una precisión de 16 bits.

Si se produce z-fighting debido al formato de bits inferior, confirme que el plano de clip 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 clip 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, normalmente 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 visualmente en el búfer de profundidad, se puede usar la utilidad Búfer de profundidad de representación en la configuración de Editor en el perfil de configuración de MRTK.

Optimizar datos de malla

La configuración optimizar datos de malla intenta quitar los atributos de vértice no utilizados 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>configuración del>proyecto Reproductor>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 abarquen 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 parte del tiempo.

Límite de GPU

Dado que la mayoría de las plataformas para aplicaciones de realidad mixta usan 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 móviles de realidad mixta como HoloLens o Oculus Quest estarán limitadas por 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. Ejecución del 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 gráficos de equipo & 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 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, ejecución de código 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 tendrá 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 de Standard MRTK, ya que este sombreador suele ejecutar muchas menos instrucciones por píxel & vértice que el sombreador de Unity Standard mientras se logran resultados estéticos comparables.

Optimizaciones de CPU Optimizaciones de GPU
Lógica de simulación de aplicaciones Operaciones de representación
Simplificación de la física Reducción de los cálculos de iluminación
Simplificar animaciones Reducir el número 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 a pantalla completa

Dibujar la creación de instancias de llamada

Uno de los errores más comunes en Unity que reduce el rendimiento es la clonación de materiales en tiempo de ejecución. Si gameobjects comparten el mismo material 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ático, el procesamiento por lotes dinámico y la creación de 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 en particular. Cada uno de los 100 cubos tendrá su propio material y, por lo tanto, no se pueden combinar en una llamada de dibujo, sino que se convertirán 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 estima 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 generados pueden variar en función de las características que se hayan habilitado en los materiales que usan el sombreador determinado. Unity solo compilará las variantes de sombreador que se usan directamente en el proyecto actual.

Ejemplo de estadísticas de sombreador de Unity Standard

Estadísticas del sombreador de Unity Standard 1

Ejemplo de estadísticas de sombreador de Standard MRTK

Estadísticas del sombreador de Standard MRTK 2

Vea también

Unidad

Windows Mixed Reality

Oculus

Optimización de malla