¿Qué estás buscando?
Hero background image
Administrar el uso de GPU para juegos de PC y consola

Este es el tercero de una serie de artículos que desglosan consejos de optimización para sus proyectos de Unity. Úselos como guía para ejecutar a velocidades de fotogramas más altas con menos recursos. Una vez que haya probado estas mejores prácticas, asegúrese de consultar las otras páginas de la serie:

Comprenda las limitaciones de su hardware de destino y cómo perfilar la GPU para optimizar la representación de sus gráficos. Pruebe estos consejos y mejores prácticas para reducir la carga de trabajo en la GPU.

Encuentre muchas más prácticas recomendadas en el libro electrónico gratuito Optimice el rendimiento de su juego para consola y PC.

SRP Batcher en el motor de Unity
SRP BATCHER TE AYUDA A AGRUPAR LAS LLAMADAS DE DIBUJO (DRAW CALLS).
Utilice el procesamiento por lotes de llamadas de sorteo

Para dibujar un GameObject en pantalla, Unity emite una llamada de dibujo a la API de gráficos (por ejemplo, OpenGL, Vulkano Direct3D). Cada convocatoria de sorteo requiere muchos recursos.

Los cambios de estado entre llamadas de extracción, como el cambio de materiales, pueden provocar una sobrecarga de rendimiento en el lado de la CPU. El hardware de PC y consola puede impulsar muchas llamadas de sorteo, pero la sobrecarga de cada llamada sigue siendo lo suficientemente alta como para justificar intentar reducirlas. En dispositivos móviles, la optimización de las llamadas de sorteo es vital. Puede lograr esto con el procesamiento por lotes de llamadas de sorteo.

El procesamiento por lotes de llamadas de dibujo minimiza estos cambios de estado y reduce el costo de CPU para representar objetos. Unity puede combinar varios objetos en menos lotes usando varias técnicas con High Definition Render Pipeline (HDRP) o Universal Render Pipeline (URP):

  • SRP batching: Habilite SRP Batcher en el activo de canalización en Avanzado. Cuando se utilizan sombreadores compatibles, SRP Batcher reduce la configuración de la GPU entre llamadas de extracción y hace que los datos del material sean persistentes en la memoria de la GPU. Esto también puede acelerar significativamente los tiempos de renderizado de la CPU. Utilice menos variantes de sombreador con un mínimo de palabras clave para mejorar el procesamiento por lotes de SRP. Consulte la documentación de SRP para ver cómo su proyecto puede aprovechar este flujo de trabajo de renderizado.
  • Instancia de GPU: Si tiene una gran cantidad de objetos idénticos con la misma malla y material, use instancias de GPU para agruparlos a través del hardware de gráficos. Para habilitar la creación de instancias de GPU, seleccione su material en la ventana Proyecto del Inspectory luego marque Habilitar creación de instancias.
  • Lotes estáticos: Para geometría inmóvil, Unity puede reducir las llamadas de dibujo para mallas que comparten el mismo material. Esto es más eficiente que el procesamiento por lotes dinámico, pero utiliza más memoria. Marque todas las mallas que nunca se mueven como Batching Static en el Inspector. Unity combina todas las mallas estáticas en una malla grande en el momento de la construcción. La clase StaticBatchingUtility también le permite crear estos lotes estáticos en tiempo de ejecución (por ejemplo, después de generar un nivel de procedimiento de partes no móviles).
  • Lotes dinámicos: Para mallas pequeñas, Unity puede agrupar y transformar vértices en la CPU y luego dibujarlos todos de una vez. Sin embargo, tenga en cuenta que no debe usar esto a menos que tenga suficientes mallas de baja poli (no más de 300 vértices cada una y 900 atributos de vértice en total). De lo contrario, habilitarlo hará perder tiempo de CPU buscando mallas pequeñas para procesar por lotes.

Puede maximizar el procesamiento por lotes de varias formas sencillas:

  • Utilice la menor cantidad posible de texturas en una escena. Menos texturas requieren menos materiales únicos, lo que facilita su procesamiento por lotes. Además, utilice Atlas de texturas siempre que sea posible.
  • Hornee siempre mapas de luz en el tamaño de atlas más grande posible. Menos mapas de luz requieren menos cambios de estado material, pero hay que estar atento a la huella de memoria.
  • Tenga cuidado de no dañar los materiales sin querer. Acceder a Renderer.material en scripts duplica el material y devuelve una referencia a la nueva copia. Esto rompe cualquier lote existente que ya incluya el material. Si desea acceder al material del objeto por lotes, utiliceRenderer.sharedMaterial en su lugar.
  • Esté atento a la cantidad de recuentos de lotes estáticos y dinámicos en comparación con el recuento total de llamadas de sorteo utilizando el Generador de perfiles o las estadísticas de renderizado durante la optimización.

Consulte la documentación sobre procesamiento por lotes de llamadas de sorteo para obtener más información.

Interfaz de Frame Debugger
FRAME DEBUGGER DESGLOSA CADA FOTOGRAMA PROCESADO.
Verifique el depurador de cuadros

Utilice Frame Debugger para congelar la reproducción en un solo cuadro y recorrer el proceso de cómo Unity construye una escena. Al hacerlo, podrá identificar oportunidades de optimización. Busque GameObjects que se rendericen innecesariamente y deshabilítelos para reducir las llamadas de dibujo por cuadro.

Una ventaja principal del Frame Debugger es que puedes relacionar una llamada de sorteo con un GameObject específico en la escena. Esto facilita la investigación de ciertos problemas que podrían no ser posibles en depuradores de marcos externos.

*NOTA*: El Frame Debugger no muestra llamadas de sorteo individuales ni cambios de estado. Si bien solo los generadores de perfiles de GPU nativos pueden brindarle información detallada sobre las llamadas de extracción y los tiempos, el Frame Debugger aún puede ser muy útil para depurar problemas de canalización o problemas de procesamiento por lotes.

Lea la documentación de Frame Debugger para obtener más detalles.

Optimice la tasa de llenado y reduzca el sobregiro

La tasa de llenado se refiere a la cantidad de píxeles que la GPU puede representar en la pantalla cada segundo. Si tu juego está limitado por la tasa de relleno, esto significa que está intentando dibujar más píxeles por cuadro de los que la GPU puede manejar.

Dibujar sobre el mismo píxel varias veces se llama sobredibujar. El sobregiro disminuye la tasa de llenado y cuesta ancho de banda de memoria adicional. Las causas más comunes de sobregiro son:

  • Geometría opaca o transparente superpuesta
  • Sombreadores complejos, a menudo con múltiples pases de renderizado.
  • Partículas no optimizadas
  • Elementos de interfaz de usuario superpuestos

Si bien debe minimizar su efecto, no existe un enfoque único para resolver el sobregiro. Experimente con las siguientes técnicas para reducir su impacto.

Reducir el recuento de lotes

Al igual que con otras plataformas, la optimización en las consolas a menudo significará reducir los lotes de llamadas de sorteo. Aquí hay algunas técnicas que podrían ayudar:

  • Utilice la selección de oclusión para eliminar objetos ocultos detrás de objetos de primer plano y reducir el dibujo excesivo. Tenga en cuenta que esto requiere procesamiento adicional de la CPU, así que use Profiler para verificar que mover el trabajo de la GPU a la CPU sea realmente beneficioso.
  • La creación de instancias de GPU también puede reducir sus lotes si tiene muchos objetos que comparten la misma malla y material. Limitar la cantidad de modelos en su escena puede mejorar el rendimiento. Si se hace con habilidad, puedes crear una escena compleja sin que parezca repetitiva.
  • SRP Batcher puede reducir la configuración de la GPU entre llamadas de extracción agrupando los comandos Bind y Draw GPU. Para beneficiarse de este procesamiento por lotes de SRP, utilice tantos materiales como sea necesario, pero limítelos a una pequeña cantidad de sombreadores compatibles (por ejemplo, sombreadores iluminados y apagados en URP y HDRP).
Interfaz de Occlusion Culling
UN EJEMPLO DE OCCLUSION CULLING.
Presta atención al sacrificio

La selección se produce para cada cámara y puede tener un gran impacto en el rendimiento, especialmente cuando se habilitan varias cámaras al mismo tiempo. Unity utiliza dos tipos de selección:

  • La selección de Frustum se realiza automáticamente en cada cámara. Garantiza que los GameObjects fuera de View Frustum no se procesen para ahorrar rendimiento.
  • Puede establecer distancias de selección por capa manualmente a través de Camera.layerCullDistances. Esto le permite seleccionar pequeños GameObjects a una distancia más corta que la propiedadfarClipPlane predeterminada. Para hacer esto, organice GameObjects en Capas. Utilice la matriz .layerCullDistances para asignar a cada una de las 32 capas un valor menor que farClipPlane (o utilice 0 para establecer de forma predeterminada farClipPlane).
  • Unity selecciona primero por capa. Solo mantiene los GameObjects en las capas que usa la cámara. Luego, la selección de Frustum elimina cualquier GameObjects fuera de Camera Frustum.
  • La selección de Frustum se realiza como una serie de trabajos que aprovechan los hilos de trabajo disponibles. Cada prueba de selección de capas es rápida (esencialmente, solo una pequeña operación de máscara). Sin embargo, este costo aún podría sumarse con una gran cantidad de GameObjects. Si esto se convierte en un problema para su proyecto, es posible que necesite implementar algún sistema para dividir su mundo en "sectores" y deshabilitar los sectores que están fuera de Camera Frustum para aliviar parte de la presión sobre el sistema de selección Layer/Frustum de Unity.
  • La selección de oclusión elimina cualquier GameObject de la vista del juego si la cámara no puede verlo. Los objetos ocultos detrás de otros objetos aún pueden representar y costar recursos. Utilice la selección de oclusión para descartarlos.
  • Por ejemplo, renderizar una habitación no es necesario si una puerta está cerrada y la cámara no puede ver el interior de la habitación. Si habilita la selección de oclusión, puede aumentar significativamente el rendimiento pero también utilizar más espacio en disco, tiempo de CPU y RAM. Unity hornea los datos de Occlusion durante la compilación y luego necesita cargarlos desde el disco a la RAM mientras carga una escena.
  • Mientras que la selección de Frustum fuera de la vista de la cámara es automática, la selección de oclusión es un proceso horneado. Simplemente marque sus objetos como Estáticos, Oclusoresu Ocluidos, luego hornee a través del cuadro de diálogo Ventana > Representación > Selección de oclusión .

Consulte el tutorial Cómo trabajar con selección selectiva de oclusión para obtener más información.

Aprovechar la resolución dinámica

La configuración Permitir cámara de resolución dinámica le permite escalar dinámicamente objetivos de renderizado individuales para reducir la carga de trabajo en la GPU. En los casos en los que se reduce la velocidad de fotogramas de la aplicación, puede reducir gradualmente la resolución para mantener una velocidad de fotogramas constante.

Unity activa este escalado si los datos de rendimiento sugieren que la velocidad de fotogramas está a punto de disminuir como resultado de estar vinculada a la GPU. También puede activar de forma preventiva este escalado manualmente con un script. Esto es útil si se acerca a una sección de la aplicación con uso intensivo de GPU. Si se escala gradualmente, la resolución dinámica puede ser casi imperceptible.

Consulte la página del manual de resolución dinámica para obtener una lista de plataformas compatibles.

Demostración de apilamiento de cámaras
APILAMIENTO DE CÁMARAS EN URP: LA PISTOLA Y EL FONDO SE RENDEN CON DIFERENTES CONFIGURACIONES DE CÁMARA.
Verifique múltiples vistas de cámara

A veces necesitas renderizar desde más de un punto de vista durante el juego. Por ejemplo, es común en un juego de disparos en primera persona (FPS) dibujar el arma del jugador y el entorno por separado con diferentes campos de visión (FOV). Esto evita que los objetos en primer plano se vean distorsionados a través del campo de visión gran angular del fondo.

Puede utilizar Camera Stacking en URP para representar más de una vista de cámara. Sin embargo, todavía se realizan importantes selecciones y renderizaciones para cada cámara. Cada cámara genera algunos gastos generales, ya sea que esté realizando un trabajo significativo o no.

Utilice únicamente los componentes de la cámara necesarios para el renderizado. En plataformas móviles, cada cámara activa puede utilizar hasta 1 ms de tiempo de CPU, incluso cuando no se procesa nada.

Utilice el nivel de detalle

A medida que los objetos se alejan, el nivel de detalle (LOD) puede ajustarlos o cambiarlos para usar mallas de menor resolución con materiales y sombreadores más simples. Esto fortalece el rendimiento de la GPU.

Consulte el curso Trabajar con LOD en Unity Learn para obtener más detalles.

Interfaz de posprocesamiento
MANTÉN LOS EFECTOS DE POSPROCESAMIENTO LO MÁS SIMPLES POSIBLE.
Efectos de posprocesamiento de perfiles

Perfile sus efectos de posprocesamiento para ver su costo en la GPU. Algunos efectos de pantalla completa, como Bloom y Depth of Field, pueden ser costosos, por lo que vale la pena experimentar hasta encontrar el equilibrio deseado entre calidad visual y rendimiento.

El posprocesamiento no fluctúa mucho en tiempo de ejecución. Una vez que haya determinado sus anulaciones de volumen, asigne a los efectos de posprocesamiento una parte estática de su presupuesto total de fotogramas.

Evite los sombreadores de teselación

La teselación subdivide una forma en versiones más pequeñas de sí misma, lo que puede mejorar los detalles mediante una mayor geometría. Aunque hay ejemplos en los que la teselación tiene más sentido, como la corteza de árbol en la demostración de Unity Book of the Dead, trate de evitar la teselación en las consolas, ya que son caras en la GPU.

Lea más sobre la demostración del Libro de los Muertos aquí.

Reemplazar sombreadores de geometría con sombreadores de cálculo

Al igual que los sombreadores de teselación, los sombreadores de geometría y vértices se pueden ejecutar dos veces por fotograma en la GPU: una vez durante el paso previo de profundidad y otra vez durante el paso de sombra.

Si desea generar o modificar datos de vértices en la GPU, un sombreador de cálculo suele ser la mejor opción, especialmente en comparación con un sombreador de geometría. Hacer el trabajo en un sombreador de cálculo significa que el sombreador de vértices que realmente representa la geometría puede funcionar mucho más rápido.

Obtenga más información sobre los conceptos básicos de Shader.

Gráficos de ocupación de frentes de onda buenos y malos
OCUPACIÓN DE FRENTES DE ONDA BUENOS Y MALOS
Apunta a una buena ocupación del frente de onda

Cuando envías una llamada de extracción a la GPU, ese trabajo se divide en muchos frentes de onda que Unity distribuye entre los SIMD disponibles dentro de la GPU. Cada SIMD tiene un número máximo de frentes de onda que pueden ejecutarse al mismo tiempo.

La ocupación del frente de onda se refiere a cuántos frentes de onda están actualmente en uso en relación con el máximo. Mide qué tan bien estás utilizando el potencial de la GPU. Las herramientas de creación de perfiles para el desarrollo de consolas muestran la ocupación del frente de onda con gran detalle.

En el ejemplo anterior del Libro de los Muertosde Unity, los frentes de onda del sombreador de vértices aparecen en verde y los frentes de onda del sombreador de píxeles aparecen en azul. En el gráfico inferior, muchos frentes de onda del sombreador de vértices aparecen sin mucha actividad del sombreador de píxeles. Esto muestra una subutilización de la GPU.

Si estás haciendo mucho trabajo de sombreado de vértices que no genera píxeles, eso podría indicar una ineficiencia. Si bien una baja ocupación del frente de onda no es necesariamente mala, es una métrica que puede utilizar para comenzar a optimizar sus sombreadores y comprobar si hay otros cuellos de botella. Por ejemplo, si tiene un bloqueo debido a la memoria o a las operaciones informáticas, aumentar la ocupación puede mejorar el rendimiento. Por otro lado, demasiados frentes de onda en vuelo pueden provocar una destrucción de la caché y una disminución del rendimiento.

Utilizar cálculo asíncrono

Si tiene intervalos en los que está subutilizando la GPU, puede aprovechar el cálculo asíncrono para mover el trabajo del sombreador de cálculo en paralelo a su cola de gráficos. Por ejemplo, durante la generación del mapa de sombras, la GPU realiza una representación de solo profundidad. En este punto se realiza muy poco trabajo de sombreado de píxeles y muchos frentes de onda permanecen desocupados.

Si puede sincronizar parte del trabajo del sombreador de cálculo con el renderizado de solo profundidad, esto mejorará el uso general de la GPU. Los frentes de onda no utilizados pueden ayudar con Screen Space Ambient Occlusion (SSAO) o cualquier tarea que complemente el trabajo actual.

Mire esta sesión sobre Optimización del rendimiento para consolas de alta gama de Unite.

Arte clave de la unidad 21 11
Consigue el libro electrónico gratuito

Una de nuestras guías más completas recopila más de 80 consejos prácticos sobre cómo optimizar tus juegos para PC y consola. Creados por nuestros ingenieros expertos en Success and Accelerate Solutions, estos consejos detallados te ayudarán a aprovechar al máximo Unity y mejorar el rendimiento de tu juego.

¿Te gustó este contenido?