Follaje de Nanite es un conjunto de sistemas integrales que utiliza el renderizado de geometría virtualizada de Nanite para conseguir un follaje denso y muy detallado a escala. El follaje de Nanite hace uso de técnicas nuevas y antiguas para renderizar mundos abiertos con vistas amplias y abiertas con mayor calidad y con un coste de fotogramas inferior al original, con instanciación, mallas articulables, voxelización, animación y características de los materiales. Al combinarlo todo, es posible imaginar unos mundos más sólidos con follaje animado realista.
Para comprender los objetivos del follaje de Nanite y hacia dónde se dirige, es importante entender que lo que ha funcionado en el pasado no es eficiente para el futuro en la creación de este tipo de mundos completos.
Veamos algunos de los aspectos en los que la «antigua forma» de desarrollar el follaje no funciona bien para el follaje de Nanite:
Enmascaramiento alfa | Representación de triángulos de Nanite completa | Material de desfase de la posición en el mundo |
Enmascaramiento alfa: Nanite no funciona bien con él, ya que introduce una gran cantidad de superposición de píxeles, además de tener que ejecutar una función de enmascaramiento potencialmente costosa. El enmascaramiento alfa también significa que el follaje se seguirá renderizando como tarjetas planas en lugar de mostrar la complejidad geométrica de la que es capaz.
Representación de triángulos de Nanite completa: esto provocaría un cribado de conjuntos por debajo del nivel óptimo y una simplificación deficiente en la distancia. Además, cada tipo de follaje requeriría grandes cantidades de espacio en el disco para almacenarlo.
Desfase de la posición en el mundo: usar el desfase de la posición en el mundo en un material para mover las hojas y ramas del follaje ha sido una forma de simular el viento. No es la mejor opción teniendo en cuenta lo que Nanite puede renderizar, ya que añade cálculos por vértice y fuerza límites de conjuntos por debajo de lo óptimo, ya que no hay forma de saber cómo un material moverá un vértice, por lo que los cálculos tienen que ser más conservadores.
Ahora que ya tienes una idea de lo que no va a funcionar bien, echemos un vistazo al proceso de follaje de Nanite para renderizar árboles completamente modelados, hasta las hojas y las acículas individuales. Necesita escalarse a grandes mundos abiertos a la vez que ahorra memoria, tiene buen rendimiento y es muy dinámico sin necesidad de mallas de nivel de detalle (LOD).
Para ello, el follaje de Nanite se compone de tres sistemas:
Los montajes de Nanite son las «partes» que se convierten en instancias muy detalladas en un fragmento de follaje. Esto puede reducir considerablemente la memoria y el tamaño en el disco.
Los vóxeles de Nanite son vóxeles agregados casi de tamaño de píxel que conservan los detalles de los triángulos, la animación y las propiedades de los materiales en función de la distancia de la cámara. Los triángulos cambian sin problemas a vóxeles para resolver el problema de renderizar mallas de triángulo agregadas densas y dinámicas. Estos vóxeles son imperceptibles a simple vista debido a su tamaño en pantalla.
El skinning de Nanite define cómo se comporta dinámicamente el follaje con sistemas como el viento, donde el viento se simula a través de una jerarquía de huesos. Al no usar desfase de posición en el mundo para simular la animación del viento, el follaje de Nanite puede usar límites de conjunto óptimos.
En el siguiente ejemplo, puedes ver cómo funciona globalmente todo esto. A medida que la cámara enfoca el detalle, puedes ver lo denso y detallado que es el árbol hasta las acículas de los pinos. A medida que la cámara se aleja, los conjuntos de Nanite se hacen lo suficientemente pequeños para convertirse en vóxeles sin problemas. Esto permite que los árboles conserven su aspecto volumétrico a distancia sin recurrir a vallas publicitarias o niveles de detalle en la distancia.
Con este árbol, tiene lo siguiente:
41 millones de triángulos
12 partes de montaje únicas
2160 instancias de partes de montaje
850 huesos esqueléticos
Cómo habilitar el follaje de Nanite
Para habilitar el follaje de Nanite en tu proyecto, ve a Configuración del proyecto > Renderizado y marca la casilla de follaje de Nanite. Deberás reiniciar el editor para que los cambios surtan efecto.
Montajes de Nanite
Los montajes de Nanite son un componente clave del follaje de Nanite y están diseñados para gestionar de forma eficiente el renderizado de geometría compleja y repetible, como las ramas y las frondas de un árbol. Los montajes funcionan tanto con recursos de malla esquelética como estática, lo que permite crear microinstancias de partes pequeñas y muy detalladas. Pueden contener hasta 65 000 instancias de otras mallas. Estas instancias se denominan «piezas» del montaje. Este enfoque ahorra una cantidad significativa de espacio en el disco y de transmisión, con un pequeño sacrificio de rendimiento durante el cribado de conjuntos.
Los montajes de Nanite toman los conjuntos de las mallas de las piezas y los codifican en la jerarquía de la malla final sin duplicar la geometría de las piezas durante la compilación. En tiempo de ejecución, Nanite se encarga de las instancias de las piezas calculando su transformación final a petición durante el cribado de conjuntos a medida que desciende en la jerarquía.
En plataformas que no sean de Nanite, los triángulos de las piezas se transforman y se fusionan en una sola malla. A partir de ahí, se simplifica la generación de una malla imprecisa que funciona igual que las mallas imprecisas normales de Nanite.
Los montajes son una parte fundamental del follaje de Nanite. Sin ellos, no habría suficiente espacio en el disco mi memoria de transmisión para renderizar un bosque de gran tamaño, como el que se muestra en la demo técnica de Unreal Fest: The Witcher 4. Por ejemplo, el espacio en disco UASSET del árbol más grande de la demo pasó de ser de 3,5 gigabytes (Gb) a aproximadamente 29 megabytes (Mb). Se midió que la memoria de transmisión de uno solo de los árboles en una vista particular bajó de aproximadamente 36 Mb a alrededor de 2,7 Mb. Este tipo de guardado hace posible renderizar 500 000 instancias de decenas de variantes de árboles en una escena, con cada árbol muy detallado y con entre uno y diez millones de polígonos cada uno.
Para obtener más información sobre cómo usar y crear montajes en Unreal Engine, consulta la sección Montajes de Nanite.
Vóxeles de Nanite
Los vóxeles de Nanite son vóxeles casi de tamaño de píxel que conservan los detalles, la animación y las propiedades de los materiales de la geometría que representan y conservan la apariencia volumétrica de los elementos, como las hojas de los árboles. Las técnicas anteriores de Nanite para evitar que las hojas pierdan su forma en la distancia funcionaron bastante bien al añadir un área de superficie a los triángulos supervivientes cuando el proceso de simplificación los eliminaría. Se ha solucionado un problema por el que la geometría del follaje se volvía menos densa al renderizar conjuntos simplificados en la distancia.
Proceso de rasterización
Los vóxeles de Nanite pueden conservar la silueta general de la geometría agregada (piezas desconectadas) durante la simplificación a distancia. Al simplificar los conjuntos de estas mallas con vóxeles habilitados, NaniteBuilder los voxeliza en conjuntos de 128 ladrillos de vóxeles de 4x4x4 como máximo. El error de simplificación de la representación de vóxeles es el factor decisivo, ya que si el simplificador pasa de triángulos a vóxeles, se pasará a los vóxeles si el error es menor que con triángulos.
En el tiempo de ejecución, los conjuntos de vóxeles se agrupan por separado de los de triángulos y se rasterizan con una permutación especial del sombreador. Los conjuntos se ordenan en cubos de profundidad y se rasterizan de delante hacia atrás para aprovechar las ventajas de las primeras pruebas Z. El resultado final suele ser mejor en la distancia que con triángulos rasterizados.
A continuación se muestran algunos ejemplos del proceso de voxelización visualizado en un recurso independiente y en la demostración técnica de The Witcher 4.
Proceso de sombreado
La región cubierta por un solo vóxel puede contener muchas superficies con normales distintas. Por tanto, en lugar de almacenar una única normal por vóxel, se almacena una distribución de normales. En concepto, esto es similar a cómo la rugosidad de los materiales controla la distribución de las microfacetas usadas para el sombreado.
Al escribir en el GBuffer, se elige estocásticamente una normal por píxel de esta distribución. En futuras versiones, la distribución se tendrá en cuenta directamente en el sombreado, al igual que la rugosidad. Esto reducirá el ruido y ya se usaba en la demo de The Witcher 4.
Esto requiere datos adicionales para almacenar las estadísticas de la distribución. Actualmente está almacenado en el canal alfa del color de los vértices, lo que significa que anulará lo que haya allí. Esto puede pasar a separar los datos independientemente del color de los vértices en el futuro.
Cómo habilitar vóxeles de Nanite
Para habilitar la voxelización de Nanite:
En el panel Detalles de una malla estática, busca la categoría Configuración de Nanite.
Localiza Conservación de la forma y usa el desplegable para seleccionar Voxelizar.
Algunas propiedades situadas debajo de este desplegable se pueden editar cuando se establece Voxelizar. No están pensadas que se ajusten a casi ningún proyecto, aunque puede haber excepciones. Algunas aún están en desarrollo y todavía no funcionan como deberían. Es probable que estos ajustes cambien o se eliminen en futuras versiones de Unreal Engine a medida que madure el follaje de Nanite.
Cómo usar el skinning de Nanite para la animación del follaje de Nanite
Cuando se quiere animar el viento en el follaje en los juegos, en gran medida se usa el desfase de la posición en el mundo (WPO) en el material, normalmente para los materiales usados en las ramas y hojas de los árboles. Dado que el desfase de la posición en el mundo de un vértice dado puede tener cualquier desfase arbitrario, es necesario que los artistas fijen el Desplazamiento máximo del WPO en cualquiera de los materiales para el peor de los casos con el fin de ayudar a rellenar los límites de cribado para que sea el adecuado en estos recursos de follaje. Sin embargo, esto puede dar como resultado unos límites demasiado conservadores que contribuyan a un elevado coste de superposición de píxeles.
Dado que el WPO también cambia la lógica del sombreador de vértices, cada material se agrupa en emisores independientes, lo que conlleva costes de GPU asociados. Si hay muchos materiales, estos contenedores de rasterizado programables pueden suponer un problema de rendimiento.
El skinning de Nanite soluciona este problema porque se pueden calcular límites más precisos a partir de matrices de skinning y todo puede usar el rasterizador de función fija.
En la siguiente captura hay 100 000 huesos actualizándose. Esto tarda unos 0,1 milisegundos en la GPU, lo que hace que el follaje de Nanite sea muy rápido y escalable. La animación deja de aplicarse automáticamente a los árboles que se encuentran por debajo de un determinado tamaño de pantalla y el viento puede afectar a los árboles que estén muy lejos para mejorar la inmersión. Esto también se aplica a la hierba y a los arbustos que usan mallas esqueléticas.
Complemento Dynamic Wind
Este complemento es experimental.
El complemento Dynamic Wind está diseñado para funcionar con el follaje de Nanite. Requiere una configuración adicional para usar un recurso de datos esqueléticos de viento dinámico para una malla esquelética concreta. Los datos de este recurso clasifican los huesos del esqueleto en grupos de simulación que ayudan al sistema a identificar de forma lógica las cadenas de huesos en la simulación, además de permitirte ajustar la influencia del viento en cada grupo.
Puedes activar el complemento desde el navegador de complementos en la categoría Renderizado.
El complemento incluye una acción de recurso programada para importar los datos necesarios desde un archivo .JSON. También incluye un esquema de Universal Scene Description (USD) que puedes aplicar a un esqueleto para proporcionar estos datos, junto con una secuencia de Python de ejemplo para crear un archivo JSON a partir de USD.
Datos del proveedor de transformaciones de viento dinámico
Las mallas esqueléticas que contienen datos de usuario de un recurso de datos de viento dinámico pueden usar estos datos para impulsar la animación del viento en un componente de malla articulable instanciado.
Para activar el viento en una malla articulable, usa el desplegable Proveedor de transformaciones del componente para seleccionar los datos del proveedor de transformaciones. Como resultado, se creará un nuevo recurso de datos de viento dinámico para la malla.
Este recurso es necesario para registrar el componente en el sistema de viento. No sirve para ningún otro propósito (de momento).
Las limitaciones actuales son las siguientes:
Añade más simulación física, como la de campo cercano.
Solo admite la dirección global del viento.
Sin colisión con jugadores u objetos.
Los datos esqueléticos de viento dinámico deben importarse con un archivo JSON.
Se espera que en el futuro esto se importe automáticamente al importar un USD.
Añade ajustes a los datos del proveedor de transformaciones de viento dinámico.
Consejos sobre el rendimiento del skinning de Nanite
Aunque el skinning de Nanite funciona mejor que el desfase de la posición en el mundo para el movimiento del viento de follaje, es necesario tener en cuenta el rendimiento.
Ten en cuenta lo siguiente:
El rendimiento del mapa virtual de sombras (VSM) requiere que desactives la animación en la distancia.
Las mallas instanciadas que están desactivadas cambian a un contenedor de rasterizado sin articular y se renderizan como una malla estática de función fija (en pose de vinculación).
Usa Tamaño de pantalla mínimo de animación en el componente para deshabilitar el skinning cuando el objeto sea pequeño en pantalla.
Es similar al ajuste Distancia de desactivación del desfase de la posición en el mundo, solo que siempre está activo. Si se deja como 0, se usará el valor predeterminado global, que es una décima parte (0,1) del tamaño en pantalla del objeto cuando se detiene la animación. Puedes cambiar esto con el comando de consola
r.Skinning.DefaultAnimationMinScreenSize.