Buscar en Unity

Una escena, 10 optimizaciones de gráficos para desarrolladores de consolas

Last updated: January 2019

What you will get from this page: Console graphics optimization tips, courtesy of Unity’s Rob Thompson, a console graphics developer (who los presentó en Unite), and our demo team. These optimizations were made to an especially difficult scene to ensure smooth 30fps performance.

Calidad AAA con los Scriptable Render Pipelines de Unity

Book of the Dead (in this article we refer to it as BOTD) was produced by Unity's demo team. It’s a real-time rendered animated short, essentially created to test-drive and show off the capabilities of the new (and still experimental) Scriptable Render Pipelines (SRP). The SRPs allow you to code the core of your render loop in C#, thereby giving you much more flexibility for customizing how your scene is drawn to make it specific to your content.

console scriptable rendering pipeline

There are two SRPs available: the High-Definition Render Pipeline (HDRP) which offers all of the features that you'd expect from a modern, AAA quality, high fidelity renderer, while the Lightweight Render Pipeline (LWRP) maintains responsive performance when scaling for mobile. BOTD uses the HDRP, and you can find advanced learning resources for the SRPs at the end of this article.

All of the assets and all of the script code for BOTD are a tu disposición in the Asset Store.

Una pasada de optimización importante para llegar a 1080p a 30 fps (o superior) en consolas

El objetivo del demo era ofrecer una experiencia interactiva en la que la gente pudiera dar vueltas por ese entorno, tenerlo entre sus manos y experimentarlo de una forma que resultara familiar desde la perspectiva tradicional de los juegos AAA. Específicamente, queríamos mostrar cómo se ejecutaba BOTD en Xbox One y PS4. Teníamos los requisitos de rendimiento de 1080p a 30 fps, o superior.

Ya que se trata de un demo, y no de un juego completo, las optimizaciones se centraron principalmente en el renderizado.

En general, la performance en BOTD es bastante constante ya que no tiene ninguna escena en la que, por ejemplo, haya miles de partículas que repentinamente cobren vida o muchos personajes animados que aparezcan súbitamente.

Para empezar, Rob y el equipo de demos hallaron la vista que mostraba la performance más deficiente en relación con la carga del GPU; lo que sigue es su captura de pantalla:

console scriptable rendering pipeline

Lo que ocurre en la escena es bastante constante; lo que varía es lo que está dentro del rango de visión de la cámara. Si pudieran economizar en esta escena, aumentarían en última instancia el rendimiento durante todo el demo.

La razón por la que esta escena tuvo un rendimiento deficiente es que se trata de una vista exterior del nivel que mira hacia el centro de la misma, de manera que la gran mayoría de los assets de la escena están en el frustum de la cámara. Esto se traduce en muchas draw calls.

En resumen, aquí se muestra cómo se renderizó esta escena:

  • Con el HDRP
  • La mayoría de las texturas creadas por artistas son de 1K y 2K, con solo unas cuantas de 4K.
  • Utiliza Baked Occlusion y Baked GI para la iluminación indirecta, y una única fuente de luz dinámica que proyecta sombras para la iluminación directa del sol.
  • Emite unos cuantos miles de draw calls en cualquier punto (draw calls y despachos de computer shaders)
  • Al inicio de la pasada de optimización, la vista estaba limitada por el GPU en PS4 Pro a unos 45 milisegundos.
Qué mostró el frame del GPU antes de la pasada de optimización

Al inicio de la pasada de optimización, Rob y el equipo observaron el frame del GPU paso a paso y vieron el siguiente rendimiento:

  • The Gbuffer was at 11ms (you can find a description of the Gbuffer layouts for HDRP in esta publicación by Unity lead graphics developer Sebastien Lagarde)
  • Motion Vectors y Screen Space Ambient Occlusion fueron bastante rápidos, con 0,25 y 0,6 ms, respectivamente
  • Los mapas de sombras de la proyección de sombras direccionales con luces dinámicas tuvieron impresionantes 13,9 ms
  • La iluminación diferida se ubicó en 4,9 ms
  • La dispersión atmosférica estuvo en 6,6 ms

Así es como se veía su frame de GPU, de principio a fin:

console GPU frame

Como puedes ver, están en 45 milisegundos y las dos líneas anaranjadas verticales muestran dónde tienen que estar para llegar a 30 fps y 60 fps, respectivamente.

10 formas en que optimizaron el renderizado para Book of the Dead

Controla el recuento de lotes

La performance del CPU no fue un problema serio para el equipo debido a que BOTD es un demo, no un juego, lo que significa que no tiene las complejidades del código script que acompaña a todos los sistemas que son necesarios para un juego completo. Nuevamente, la principal preocupación era optimizar el trabajo de renderizado.

However keeping the batch count low is still a valuable tip for any platform. The team did this by using Occlusion Culling, and, primarily, instanciación de GPU. Avoid using Dynamic batching on consoles unless you are sure it’s providing a performance win.

En este caso, la instanciación del GPU fue el método más útil. Sin este, hubiese habido 4500 lotes para esta escena. Al usarlo, esta cantidad se redujo a 1832.

Otro aporte: la cantidad de assets individuales que se utilizaron para crear esta escena es realmente muy baja. Al utilizar assets de buena calidad, y colocarlos de manera inteligente, el equipo creó escenas complejas que no se ven repetitivas, y mantuvo el recuento de lotes bajo con la instanciación de GPU.

Esta es la escena sin instanciación.

console scriptable rendering pipeline

Y aquí está con instancias:

console scriptable rendering pipeline

Usar los numerosos núcleos disponibles en las consolas

Tanto Xbox One como PS4 son dispositivos multinúcleo, y para poder obtener la mejor performance del CPU, tenemos que intentar mantener estos núcleos ocupados todo el tiempo.

If you follow Unity news, you’ll know that Unity is currently developing un sistema multihilo de alta performance, that will make it possible for your game to fully utilise the multicore processors available today and in the future. (Very) briefly, this system comprises three sub-systems: the Sistema de componentes de entidades o Entity Component System, the Sistema de trabajo C# and the Burst Compiler.

El nuevo sistema multihilo se encuentra todavía en fase experimental. En el sistema de gráficos de Unity, puedes probarlo a través del modo Graphics Jobs (que también se encuentra en fase experimental). Puede encontrar los controles de Graphics Jobs en Player Settings -> Other Settings (Ajustes del jugador -> Otros ajustes).

console Graphics Jobs

El modo Graphics Jobs te ayudará a optimizar la performance en casi todas las circunstancias en la consola a menos que literalmente solo estés extrayendo un puñado de lotes. Hay dos tipos disponibles:

  • Legacy Jobs, disponibles en PS4, y DirectX 11 para Xbox One
    • Reduce la presión de la hebra principal al distribuir el trabajo entre otros núcleos. Ten presente que en escenas muy grandes, puede haber un cuello de botella en la "Render Thread", una hebra que Unity utiliza para comunicarse con la APl de gráficos de la plataforma.
  • Native Jobs, disponible en PS4 y DirectX 12 para Xbox One (próximamente)
    • Distribuye la mayor parte del trabajo entre todos los núcleos disponibles y es la mejor opción para escenas grandes.
    • Siempre será la mejor opción de 2018.2 en adelante (en la versión 2018.1 o anteriores, puede dar más trabajo a la hebra principal, lo que dará lugar a regresiones de la performance).

Utiliza las herramientas de análisis de la performance del titular de la plataforma

Microsoft and Sony provide herramientas excelentes for analyzing your project’s performance both on the CPU and on the GPU. These tools are available to you for free if you're working on console. Learn them early on and keep using them throughout your development cycle. Pix for Xbox One is Microsoft's offering and the Razor Suite is Sony's; as Rob says, they are your main tools in your arsenal when it comes to optimization on these platforms.

Perfila tus efectos posproceso

Rob afirma que ha perfilado juegos de Unity en PS4 en los que, y esto no es conocido por los desarrolladores, hasta ⅔ de la framerate es utilizada por el posprocesamiento. Esto con frecuencia provocaba la descarga de assets de posprocesamiento de la Asset Store que se desarrollaron principalmente para PC. Parece que funcionan bien en la consola pero, de hecho, las características de performance son realmente malas.

So, when apliques efectos como estos, profile how long they take on the GPU, and iterate until you find a happy balance between visual quality and performance. And then, leave them alone, because they comprise a static cost in every scene, meaning you know how much GPU bandwidth is left over to work with.

Evitar usar el teselado (a menos que tengas una buena razón para hacerlo)

En general, no es recomendable usar el telesado en los gráficos de juegos de consola. En la mayoría de los casos, es mejor que utilices los assets equivalentes desarrollados por artistas y no aplicarles el teselado durante el runtime en el GPU.

Sin embargo, en el caso de BODT, tuvieron una buena razón para utilizar el teselado, y esta era renderizar la corteza de los árboles.

console tesselation

El desplazamiento por teselado les permitió añadir las hendiduras profundas y detalles rugosos en la geometría que se sombrearán automáticamente de manera correcta de una manera en que no hará un mapeo normal.

Ya que los árboles son objetos "heroicos" en gran parte de BOTD, esto se justificaba. Esto se hizo utilizando la misma malla en los árboles en LOD 0 y LOD 1. La diferencia entre ellos es simplemente que el desplazamiento por teselado se redujo de manera que ya no estuviese activo en el momento en que llegaron al LOD uno.

Busca en todo momento una ocupación saludable en el frente de onda en el GPU

Ok, es un trabalenguas, pero realmente vale la pena comprender la ocupación del frente de onda.

Puedes pensar en el frente de onda como un paquete de trabajo del GPU. Cuando envías una draw call al GPU, o despachas un shader de cálculo, ese trabajo se divide entonces en muchos frentes de onda y esos frentes de onda se distribuyen entre todos los SIMD de todas las unidades de cálculo que están disponibles en el GPU.

console wave front occupancy

Cada SIMD tiene un número máximo de frentes de onda que puede ejecutarse a la vez y, por lo tanto, tenemos un número máximo total de frentes de onda que pueden ejecutarse en paralelo en el GPU en un punto cualquiera. Nos referimos a ocupación de frentes de onda a la cantidad de estos frentes de onda que utilizamos, y esta es una métrica muy útil para poder comprender qué tan bien estamos aprovechando el potencial del GPU para el paralelismo.

Pix and Razor pueden mostrar la ocupación del frente de onda a través de detalles increíbles. Los gráficos anteriores son de Pix for Xbox One. A la izquierda tenemos un ejemplo de una buena ocupación del frente de onda. Abajo en la franja verde podemos ver algunos frentes de onda de shaders de vértice que están ejecutándose, y encima, en azul, podemos ver algunos frentes de onda de shaders de píxeles que están ejecutándose.

Sin embargo, a la derecha podemos ver un problema de performance. Muestra mucho trabajo del shader de vértices que no está generando mucha actividad del shader de píxeles. Esto quiere decir que se está utilizando el potencial del GPU de manera insuficiente. Esto nos lleva al siguiente consejo para la optimización.

¿Cómo ocurre esto? Este escenario es típico cuando estás haciendo un trabajo con shaders de vértices que no generan píxeles.

Utiliza Depth Prepass

Un análisis más exhaustivo de Pix and Razor demostró que el equipo se estaba llenando de overdraw durante la pasada de Gbuffer. Esto es especialmente malo en una consola cuando se analizan los objetos probados en fase alfa.

En la consola, si envías instrucciones para desechar píxeles o escribes directamente la profundidad en tu shader de píxeles, no puedes aprovechar el rechazo inicial de profundidad. Estos frentes de onda de shaders de píxeles comienzan a ejecutarse incluso si el trabajo al final va a desecharse.

La solución aquí fue añadir una Depth Prepass. Una Depth Prepass implica renderizar la escena por anticipado únicamente en lo que respecta a la profundidad, solo con shaders muy ligeros, que después pueden sentar las bases de un rechazo de profundidad más inteligente cuando estás al límite con los shaders de Gbuffer.

The HDRP now includes a Depth Prepass for all alpha tested objects, but you can also switch on a full Depth Prepass if you want. The settings for controlling HDRP, what render passes are used, and features enabled, are all made available via the .

Si buscas un proyecto HDRP para el HD Render PipelineAsset, verás muchas casillas de comprobación que controlan todo lo que hace HDRP.

Para BOTD, el uso de Depth Prepass fue una gran ganancia para el GPU pero se debe tener en cuenta que tiene el costo general de añadir más lotes que serán aprovechados por el CPU.

Reduce el tamaño de tus objetivos de renderizado de mapas de sombras

Tal como se mencionó anteriormente, los mapas de sombras en esta escena se generan a través de una sola luz direccional que proyecta sombras. Se emplearon cuatro desgloses de mapas de sombras y en un principio renderizaban un mapa de sombras de 4K con una profundidad de 32 bits, ya que este es el valor predeterminado para proyectos de HDRP. Cuando se trata de renderizar mapas de sombras, la resolución del mapa de sombra es siempre el factor limitante aquí; esto se fundamentó con un análisis en Pix and Razor.

Reducir la resolución del mapa de sombras era la solución evidente, aunque estuvo pudiese tener impacto en la calidad.

The shadow map resolution was dropped to 3k, which provided a perfectly acceptable trade-off against performance. The demo team also added an option specifically to allow developers to render to 16-bit depth Shadow maps. If you want to give that a go for yourself descargar the project assets.

Finalmente, al cambiar la resolución de su mapa de sombras, también tuvieron que cambiar algunos ajustes en la luz.

Reduce size of shadow

En este punto, el equipo revisó su mapa de sombras y reubicó la cámara de sus mapas de sombras para intentar aprovechar al máximo la nueva resolución reducida que tenían ahora. Entonces, ¿qué hicieron después?

Extraer únicamente la división con el último mapa de sombras (con el plano más abierto) una vez en la carga de nivel

Debido a que la cámara de los mapas de sombras no se mueve mucho, pudieron lograrlo. Esa división con el plano más abierto se utiliza normalmente para renderizar las sombras que están más lejos de la cámara del jugador.

Ellos no notaron una pérdida de calidad. Resultó ser una optimización inteligente ya que les ahorró tiempo del framerate del GPU y, a la vez, redujo la cantidad de lotes en el CPU.

Después de esta serie de optimizaciones, la fase de creación de mapas de sombras pasó de 13 ms a apenas menos de 8 ms; la pasada de iluminación cayó de 4,9 ms a 4,4 ms, y la pasada atmosférica pasó de 6,6 ms a 4,2 ms.

Aquí es donde el equipo llegó al final de la optimización de los mapas de sombras. Ahora están dentro del límite donde podrían ejecutar a 30 fps en PS4 Pro.

console GPU frame

Utiliza Async Compute

Async Compute is a method available for minimizing periods of underutilization on the GPU with useful shader de cálculo work. It’s currently only supported on PS4, but coming to DX12 for Xbox One very soon. It's accessible through Unity's Command Buffer interface. It's not just exclusively for the SRP but is primarily aimed at it. Code examples are available in the BOTD assets, or look at the HDR PSOS.

La fase de solo profundidad, que es lo que estás haciendo con los mapas de sombras, es, por tradición, un punto donde no aprovechas al máximo el potencial del GPU. Async Compute te permite trasladar tu trabajo con los shader de cálculo para que se ejecute en paralelo con tu cola de gráficos, lo que te permitirá aprovechar los recursos que la cola de gráficos no está aprovechando al máximo.

BOTD emplea Async Compute para su recopilación de listas de luz en mosaico de la iluminación diferida, y todo esto se hace principalmente con los shaders de cálculo en la consola en HDRP. Los emplea también para sus cálculos de SSAO. Ambos se superponen con el renderizado de mapas de sombras para llenar los vacíos en la utilización del frente de ondas.

For a run-through of some conceptual code where Async Compute is employed, tune into la sesión de Unite de Rob at 35:30.

Mas recursos

¡Debemos saberlo! ¿Te gustó este contenido?

Sí. Que sigan llegando Me da igual. Podría ser mejor
Lo tengo

Usamos cookies para brindarte la mejor experiencia en nuestro sitio web. Visita nuestra página de política de cookies si deseas más información.