Filosofía de diseño de Niagara
¿Por qué reinventar los efectos visuales para Unreal Engine?
Unreal Engine está ampliando su base de usuarios y ahora se utiliza en numerosos sectores fuera del espacio del desarrollo de juegos. Algunos ejemplos son:
- Visualización arquitectónica
- Diseño industrial, como diseños para automoción
- Producción de TV virtual y cine
Nuestros usuarios son más diversos que nunca, desde estudiantes de diseño a pequeños desarrolladores indie, hasta grandes equipos de estudios profesionales o individuos y empresas de fuera del sector de los juegos. A medida que avanzamos, los desarrolladores de Epic no pueden saberlo todo acerca de todos los sectores que utilizan Unreal Engine. Queríamos crear efectos visuales (VFX) que pudiesen funcionar para todos nuestros usuarios, sea cual sea su sector.
Nuestros objetivos para un nuevo sistema de VFX
Queríamos crear un sistema que proporcionase a todos los usuarios la flexibilidad necesaria para crear los efectos que necesitasen. Nuestros objetivos para el nuevo sistema de VFX eran:
- Poner todo el control en manos de los artistas.
- Ser programable y personalizable en todos los ejes.
- Proporcionar mejores herramientas para depuración, visualización y rendimiento.
- Admitir datos de otras partes de Unreal Engine o de fuentes externas.
- Permanecer fuera del camino del usuario.
Cómo Niagara alcanza nuestros objetivos
Compartición de datos
El control total del usuario empieza por el acceso a los datos. Queremos que el usuario pueda utilizar cualquier dato de cualquier parte de Unreal Engine, además de usar datos de otras aplicaciones. Así que decidimos exponerlo todo al usuario.
Carga de partículas
Para exponer todos los datos al usuario, tenemos que establecer cómo puede utilizarlos. Los espacios de nombres proporcionan contenedores para los datos jerárquicos. Por ejemplo, Emitter.Age contiene los datos de un emisor; Particle.Position contiene datos de una partícula. Nuestro mapa de parámetros es la carga de partículas que lleva todos los atributos de las partículas. Como resultado, todo se convierte en opcional.
Es posible añadir numerosos tipos de datos
Es posible añadir cualquier tipo de dato como parámetro de partículas. Es posible añadir estructuras complejas, matrices de transformación o indicadores booleanos. Es posible añadir esos datos o cualquier otro tipo de datos y utilizarlo en la simulación de los efectos.
Combinación del paradigma de grafos y el paradigma de pilas
Tanto el paradigma de pilas (como el que se utiliza en Cascade) como el paradigma de grafos (como el que se utiliza en los blueprints) aportan ventajas. Las pilas proporcionan un comportamiento modular y legibilidad. Los grafos dan más control a los usuarios sobre el comportamiento. Nuestro nuevo sistema de efectos combina las ventajas de ambos paradigmas.
Jerarquía de la estructura híbrida de Niagara
Módulos
Los módulos funcionan según un paradigma de grafo: puedes crear módulos con HLSL en el editor de scripts utilizando un grafo de nodos visual. Los módulos interactúan con los datos comunes, encapsulan comportamientos y los apilan.
Emisores
Los emisores funcionan según un paradigma de pila: sirven como contenedores de módulos y se pueden apilar para crear distintos efectos. Un emisor tiene un único fin, pero es reutilizable. Los parámetros se transfieren hasta el nivel del emisor desde los módulos, pero es posible modificar los módulos y los parámetros en el emisor.
Sistemas
Igual que sucede con los emisores, los sistemas funcionan según un paradigma de pila y también funcionan con una línea de tiempo de un secuenciador, que se puede utilizar para controlar cómo se comportan los emisores de un sistema. Un sistema es un contenedor de emisores. El sistema combina los emisores para obtener un efecto. Al editar un sistema en el editor de Niagara, es posible modificar y sobrescribir cualquier parámetro, módulo o emisor del sistema.
Pila de selección y grupos de pilas de Niagara
La simulación de partículas en Niagara funciona, conceptualmente, como una pila: la simulación fluye desde la parte superior de la pila hasta la parte inferior y ejecuta los módulos por orden. Lo más esencial es que se asigna cada módulo a un grupo que describe cuándo se ejecuta el módulo. Por ejemplo, los módulos que inicializan partículas o que actúan cuando se genera una partícula están en el grupo Generación de partículas.
Dentro de cada grupo puede haber distintas etapas, que se llaman en puntos específicos del ciclo de vida de un sistema. Todos los emisores, los sistemas y las partículas tienen las etapas Generación y Actualización de forma predeterminada. Las etapas de generación se invocan en el primer fotograma en el que existe un grupo. Por ejemplo, los sistemas invocan su etapa Generación cuando se instancia el sistema por primera vez en el nivel y se activa. Las partículas invocan su etapa Generación cada vez que el emisor emite una partícula y se ejecutan las instrucciones de Generación para cada partícula que se crea. Se invocan las etapas Actualización en cada fotograma en el que el sistema, el emisor o la partícula estén activos.
También existen etapas avanzadas, como las de Eventos y Etapas de simulación, que se pueden añadir al flujo de Generación y Actualización. Se invocan Eventos cada vez que una partícula genera un evento nuevo y hay un emisor encargado de gestionar dicho evento. Siempre que sea posible, las etapas de gestión de eventos tienen lugar en el mismo fotograma, pero después del evento que las origina. Las Etapas de simulación son una característica avanzada de la GPU. Esta característica permite aplicar varias etapas Generación y Actualización sucesivamente y resulta útil para construir estructuras complejas como las simulaciones de fluidos.
Un módulo es un elemento, pero un elemento es un módulo. Los módulos son activos editables que un usuario puede crear. Los elementos son partes de un sistema o un emisor que el usuario no puede crear. Ejemplos de objetos son las propiedades del sistema, las propiedades de los emisores y los renderizadores.
Etapas, grupos, espacios de nombres y encapsulación de datos
Al añadir cada módulo a una etapa (Actualización, Generación, Evento o Simulación) de un grupo (Sistema, Emisor o Partícula), es posible controlar cuándo se ejecuta un módulo y con qué datos funciona. Los grupos de pilas están asociados con espacios de nombres que definen qué datos pueden leer o escribir los módulos de ese grupo.
Por ejemplo, los módulos que se ejecutan en el grupo Sistema pueden leer y escribir parámetros en el espacio de nombres Sistema, pero solo pueden leer los parámetros que pertenecen a los espacios de nombres Motor o Usuario. A medida que la ejecución desciende por la pila del grupo Sistema hasta el grupo Emisor, los módulos que se ejecutan en el grupo Emisor pueden leer y escribir parámetros en el espacio de nombres Emisor, pero solo pueden leer los parámetros que pertenecen a los espacios de nombres Sistema, Motor y Usuario. Los módulos del grupo Partícula solo pueden leer los parámetros de los espacios de nombres Sistema y Emisor.
Puesto que los módulos de los grupos Emisor pueden leer los parámetros del espacio de nombres Sistema, es posible realizar la simulación relevante para todos los emisores una sola vez por parte de los módulos del grupo Sistema y, después, leer los resultados de esta simulación (almacenados en el espacio de nombres Sistema) desde los módulos del grupo Emisor en cada emisor específico. Esto continúa con los módulos del grupo Partícula, que pueden leer los parámetros de los espacios de nombres Sistema y Emisor. Consulta la tabla siguiente para obtener una representación más concisa de estas relaciones.
| Grupo de módulos | Leer de los espacios de nombres | Escribir en los espacios de nombres |
|---|---|---|
| Sistema | Sistema, Motor, Usuario | Sistema |
| Emisor | Sistema, Emisor, Motor, Usuario | Emisor |
| Partícula | Sistema, Emisor, Partícula, Motor, Usuario | Partícula |