Epic Games ha vuelto a revolucionar la industria del videojuego con Unreal Engine 5 y es en gran medida a consecuencia de Nanite. La creación de esta herramienta ha supuesto un auténtico “Game Changer” para los medios especializados, los desarrolladores independientes y los estudios de videojuegos.
Es un sistema de virtualización de geometría que usa un nuevo formato de mallas internas y tecnología de renderizado. Su objetivo es convertir grandes cantidades de triángulos en objetos y detalles. Esto lo realiza de una manera simple, eficiente y con una escala de píxel.
Para poder entender de la mejor manera posible cuál es su funcionamiento y lo que ha supuesto su creación, vamos a hacer un repaso de los motores anteriores.
Un motor gráfico cuando tiene que dibujar una escena, tiene un listado de objetos que deberá mostrar en pantalla. Dependiendo de cómo sea el mapa, esa lista estará compuesta por más o menos objetos. Y cada uno de esos objetos tendrá las instrucciones de cómo se debe dibujar en la pantalla.
Esta opción es en la que Unreal le diría a Nanite que dibuje el objeto en nuestra pantalla. A esta parte del renderizado se le llama DrawCall, lo que en español vendría a significar “llamada de dibujado”. Todos los motores gráficos tienen ciertas técnicas o ¨trucos¨ para ahorrar en estos DrawCall.
Esto es lo que determina si tendremos más o menos rendimiento. Aparte de la cantidad de polígonos que tienen estos objetos, otro de los trucos es el Culling. Esta táctica implica que no se dibujen las cosas que no vemos, para ahorrarle el trabajo a la gráfica.
Aunque pueda parecer una tarea compleja, ir mostrando y ocultando los objetos a medida que se mueve la cámara es algo muy simple y sencillo para una tarjeta gráfica.
Para que puedas ver un ejemplo práctico hemos preparado esta escena. Está hecha a partir de formas simples para que sea mucho más sencillo de entender.
Como podemos observar tenemos una escena llena de cubos, que tardaría mucho en procesar.
Si no necesitamos ver toda la escena podemos colocar al jugador en una posición determinada. En este caso estaría en el círculo azul y observaría lo que hay dentro de las flechas azules.
A partir de ahora, se verían de esta forma los elementos. Ya no veríamos el plano entero, si no la mitad que hemos seleccionado.
Como veis, ha desaparecido todo lo que está fuera de cámara. Pero siguen estando, en color oscuro, muchos elementos que podrían eliminarse.
La parte de la zona roja no se encuentra visible en pantalla, veríamos solo la parte gris.
Todo lo que aparece en rojo son polígonos susceptibles de no ser cargados, que el motor podría ahorrar. Esta es una escena sencilla, pero en escenarios realistas, cada metro de escenarios, suponen miles de polígonos. Esto conlleva esfuerzo de la gráfica y tiempo de procesado.
Hasta ahora el proceso de Culling funciona por objeto cargado. De este modo, si se ve un pixel del objeto en pantalla, se cargará el objeto al completo.
Por lo tanto, si tenemos un objeto de 10.000 polígonos, estaremos gastando los recursos de todo el objeto, aunque solo veamos un píxel. Esta característica hace que gastemos los recursos de dibujado en algo que no vemos en pantalla y reduce la optimización de nuestros proyectos en Unreal.
Cuando añadimos un asset en Unreal y lo transformamos a Nanite, el programa rompe el objeto en pequeñas partes que formarán una nueva malla formada por clusters, que son grupos de triángulos.
De esta forma cuando un objeto salga proporcionalmente de la pantalla, o una de sus partes no se vea, el motor se encarga de ocultarlas y no hacer el proceso de dibujado. Nanite viene a optimizar este proceso para que la carga de polígonos sea mucho menor y la visualización se vuelva realmente eficiente dentro de Unreal.
En este ejemplo podemos apreciar como se han dividido los cubos en triángulos de diferentes colores. Con Nanite se mostrarán solo los triángulos que sean visibles, sin necesidad de cargar el objeto al completo.
Como podemos ver, esta imagen esta generada con todos los triángulos agrupados en pequeñas regiones. A estas regiones se les conoce como Meshlets. Se dividen por regiones, ya que si no a la gráfica le costaría mucho trabajo realizarlo por cada triángulo.
Esta operación se hace cuando importamos un objeto en Unreal con Nanite de forma automática. Al agruparlo de esta forma, el proyecto disminuye su carga. Cada color es una región, y cuando una región no se ve en cámara, esta se elimina de la gráfica. Así la parte que queda fuera de cámara se oculta directamente, así como las que están detrás de otros meshlets.
Aquí podemos ver en tiempo real como únicamente se ve lo que entra en la cámara. Gracias a este proceso se realiza una gestión mucho más eficiente de la visualización en Unreal Engine y podemos mostrar más triángulos que antes.
Este es el verdadero poder de Nanite y el causante del cambio en la industria, pero no es su única ventaja. Nanite también tiene la capacidad de simplificar los objetos a medida que nos alejamos de ellos. Es capaz de realizar nuevos clusters de triángulos cada vez más grandes, de manera totalmente dinámica.
La revolución de Nanite en Unreal solo acaba de empezar. ¿Lo has probado ya?