Saltar al contenido principal
junio 18, 2019

WaveEngine 3.0 Preview

Hoy lanzamos el primer avance de Wave Engine 3.0. Esta versión es el resultado de más de un año de investigación y desarrollo llevado a cabo con gran esfuerzo para conseguir reinventar esta tecnología. He aquí un resumen de lo que significa Wave Engine 3.0.

Y si quieres saber más sobre nuestro motor gráfico más novedoso, ¡descubre Evergine!

En los últimos años, las tecnologías relacionadas con la generación de gráficos por ordenador han evolucionado muy rápidamente. Han aparecido nuevas APIs gráficas como DirectX 12 de Microsoft, Vulkan de Khronos Group o Metal de Apple que han ofrecido cada una de ellas cambios radicales sobre las anteriores tecnologías DirectX 10/11 y OpenGL proporcionando un mayor control del driver por parte de los desarrolladores para obtener soluciones con un rendimiento nunca visto hasta ahora.

Hace más de un año estas nuevas APIs fueron analizadas por el equipo de Wave Engine para que el motor pudiera soportarlas. En ese momento ya se publicaron versiones de Wave Engine 2.x con grandes resultados dentro del sector industrial, pero esta versión utilizaba una capa de bajo nivel que funcionaba como capa de abstracción sobre las APIs gráficas DirectX 10/11 y OpenGL/ES.

Sin embargo, los cambios que planteaban estas nuevas APIs gráficas (DirectX 12, Vulkan y Metal) eran tan importantes que necesitaban un esfuerzo más profundo que simplemente añadir funcionalidades adicionales a la capa de Bajo Nivel para soportar nuevas funciones gráficas como en las versiones anteriores.

Los cambios iban más allá, prácticamente suponían un cambio de «las reglas del juego» por lo que, tras múltiples investigaciones y siguiendo las recomendaciones técnicas de NVidia, se determinó que no era posible adaptar la antigua capa Low-Level con soporte para DirectX 10/11 y OpenGL/ES a las nuevas APIs. La mejor solución para sacar el máximo partido al último y próximo hardware gráfico era desarrollar una capa completamente nueva sobre los fundamentos de DirectX 12, Vulkan y Metal y, a continuación, adaptar y simular ciertos conceptos sobre DirectX 10/11 y OpenGL/ES para lograr la retrocompatibilidad en dispositivos antiguos.

Ninguna de las APIs de DirectX 12, Vulkan y Metal son completamente iguales pero presentan varias similitudes importantes con la intención de minimizar la comunicación entre la CPU y la GPU, conceptos como GraphicsPipeline, ComputePipeline, ResourceLayout, ResourceSet, RenderPass, CommandBuffer o CommandQueue deben ser soportados por la nueva capa Low-Level Wave Engine.

Wave Engine 3.0 nació desde el principio por la necesidad de soportar estas nuevas APIs gráficas y de ser más ligero y eficiente que sus versiones anteriores, gracias a los avances en la tecnología .NET de Microsoft, como las librerías NETStandard y el nuevo runtime llamado NETCore.

Así pues, empezamos a construir Wave Engine 3.0 desde la base para poder implementar cambios importantes, de modo que todas las bibliotecas deben ser ahora NetStandard 2.0 para soportar NetCore en múltiples plataformas. Este cambio ha supuesto una revisión en profundidad de cada librería de Wave Engine en la que el rendimiento también se ha convertido en uno de los objetivos más importantes, por lo que desde el principio se hicieron muchas pruebas para comparar el rendimiento alcanzado. A continuación, se puede profundizar en estos resultados, pero en esta imagen, podemos ver la mejora de rendimiento respecto a Wave Engine 2.5 (última estable) frente a Wave Engine 3.0 utilizando DirectX11 en ambas:

Después de mucho trabajo esta es la nueva arquitectura de Wave Engine 3.0:

En este diagrama se pueden ver todas las tecnologías que utiliza Wave Engine 3.0 para proporcionar la mayor flexibilidad y adaptabilidad a cualquier tipo de proyecto industrial.

Para explicarlo podemos dividirlo verticalmente en 4 secciones que empezando por la parte inferior serían:

Ahora Wave Engine puede dibujar sobre DirectX12/11, OpenGL/ES, Vulkan, Metal y WebGL. Esto supone una mayor versatilidad, que nos permite obtener el mejor rendimiento posible en cada una de las plataformas y arquitecturas del mercado.

El runtime por defecto es .NetCore 3.0 en Windows, Linux y MacOS aunque también se puede compilar de forma nativa a una plataforma de destino utilizando AOT. Esta es también la única opción en las plataformas como iOS y Android, que utilizan el AOT de Xamarin, y la única opción en la Web donde se utiliza el AOT Mono-Wasm.

En este nivel, tendríamos la capa de bajo nivel de Wave Engine que se conecta a la plataforma, no solo a nivel de gráficos, sino también para el sonido, el acceso a archivos, los sensores del dispositivo y las entradas. Encima estaría el framework de Wave Engine, los componentes y las extensiones; todo ello distribuido como paquetes Nugets.

Uno de los factores importantes dentro del sector industrial es, no sólo poder crear nuevas aplicaciones con Wave Engine 3.0, sino también poder integrar los visores en los sistemas y aplicaciones existentes. Para ello, la capa de generación de ventanas ha sido diseñada de forma versátil para soportar integraciones en aplicaciones desarrolladas en multitud de tecnologías a través de múltiples plataformas como WPF, WindowsForms, UWP, SDL, UI Kit, Android UI y HTML/JavaScript en la Web.

Todos estos son los nuevos pilares de Wave Engine 3.0, pero las novedades no acaban aquí. El equipo está trabajando en mejorar todos y cada uno de los elementos que componen el motor gráfico utilizando las últimas herramientas disponibles. A continuación repasamos estos avances:

Características principales:

Nuevo sistema de actualización

WaveEngine 3.0 viene con una aplicación de lanzamiento separada del editor que te permite crear nuevos proyectos, abrir los existentes, actualizar la versión NuGet de WaveEngine o incluso gestionar y descargar diferentes versiones del motor. Estas versiones se instalan en tu máquina en diferentes carpetas para que puedas trabajar en diferentes proyectos y utilizar una versión diferente del motor para cada uno de ellos.

Cuando esté disponible una nueva versión del motor, el lanzador te dirá automáticamente que hay una nueva versión y te permitirá descargarla, así como actualizar cualquier proyecto existente en el que estés trabajando a la última versión.

La aplicación del lanzador se ha integrado en la barra de tareas del sistema operativo Windows para que los usuarios puedan abrir rápidamente los proyectos recientes, sin tener que ejecutar el lanzador.

Nuevo WaveEditor

El nuevo editor ha sido completamente reescrito para aumentar la funcionalidad a niveles nunca vistos en Wave Engine. El nuevo editor es más rápido, más eficiente, más fácil de usar y más potente en todos los aspectos.

¿Por qué un nuevo editor? El editor de Wave Engine 2.x se desarrolló utilizando GTKSharp 2.42, una tecnología multiplataforma que nos permitía crear interfaces en Windows, Linux y MacOS. GTK seguía evolucionando, pero el envoltorio de C# de Xamarin (GTKSharp) no, y esto empezó a causarnos algunos problemas con las características de los sistemas operativos modernos, como la gestión de DPI o la compatibilidad con x64. Entonces planteamos la opción de crear nuestro propio wrapper de GTK 3 y portar todo el editor, pero tras un estudio de nuestros usuarios, resultó que el 96% de ellos utilizaban Wave Engine para Windows. Tras este hecho, nos planteamos que seguir dando soporte a Linux y MacOS era muy costoso para el equipo y decidimos concentrar todos nuestros esfuerzos en desarrollar un nuevo editor en WPF para Windows, con el que conseguiríamos una mejor integración con este sistema operativo al ser el utilizado por la gran mayoría de nuestros usuarios.

El nuevo editor 3.0 es más sólido, consta de 2 procesos independientes: uno que gestiona el renderizado de las vistas 3D, y otro que gestiona la UI y los diferentes layouts. Esto permite que el editor no se cierre ni se bloquee cuando se produce un error durante el renderizado de las vistas, e incluso nos permite recuperar el renderizado reiniciando el proceso, lo que ha supuesto un aumento de la estabilidad del nuevo editor.

El nuevo editor Wave Engine 3.0 es completamente flexible; permite modificar el diseño del usuario para cada proyecto. Todos los iconos han sido rediseñados para ser vectorizados, por lo que no volveremos a ver iconos pixelados en pantallas de alta densidad. Incluye un gestor de temas que permitirá cambiar entre temas oscuros y claros para facilitar la visualización en diferentes pantallas. Los contenidos de una aplicación son aún más fáciles de crear y editar, es posible visualizar todos los contenidos y modificarlos en tiempo real. Hay un nuevo sistema de sincronización de cambios externos, lo que significa que si modificamos un activo externamente, el editor será informado y se mantendrá actualizado.

Se han implementado nuevos visores para cada tipo de activo, más completos y funcionales. Estos visores no son procesos externos como en la versión anterior del editor, sino que se ejecutan dentro del nuevo editor y en el mismo contexto, lo que aumenta considerablemente la velocidad de carga.

Nuevo Visor de Efectos

Permite escribir tu propio efecto. Se ha diseñado una extensión para HLSL que ayudará a portar automáticamente los shaders creados a todas las plataformas soportadas por Wave Engine. Esta extensión es un metadato que define y modela fácilmente las propiedades, los pases de sombreado, los valores por defecto…

Nuevo Visor de Materiales

Muestra sobre una superficie 3D un material que podemos modificar mientras vemos los cambios en tiempo real.

Nuevo Visor de Capas de Render

El pintado de entidades se agrupa por capas de render, en este visor se crean y modifican las capas, permitiendo modificar la dirección de ordenación, la configuración del rasterizador, la mezcla de colores (BlendState) y el control de profundidad (DepthStencilState).

Nuevo Visor de Muestras

Este visor permite crear y editar activos de Sampler, lo que permite modificar el modo en que Wave Engine tratará las texturas a las que se aplica cada Sampler.

Nuevo Visor de Texturas

Al igual que en el resto de visores, también se ha incluido un nuevo visor de texturas en el que se puede indicar el formato de salida, el % de escalado, si la textura es de tipo NinePath, si es necesario crear MipMaps o si la textura incluye el canal alfa premultiplicado, así como el Sampler que se utilizará para dibujar.

Nuevo Visor de Modelos

La visualización de los modelos ha mejorado con el desarrollo del nuevo visor y la incorporación del formato GLTF. El visor permite observar los modelos, así como modificar la iluminación para mejorar el detalle. Es posible acceder a cada una de las animaciones incluidas en el modelo y asignar eventos clave a momentos concretos de cada animación. Estos eventos pueden ser utilizados para lanzar métodos en nuestro código, reproducir sonidos, activar efectos y otras actividades que imaginemos.

Nuevo Visor de Audio

Otra de las mejoras de esta versión es el nuevo visor de archivos de Audio, donde se puede ver la forma de onda del archivo y configurar las características de salida como la frecuencia de muestreo o el número de canales.

Nuevo Visor de Escenas

Este visor es el centro del editor. El visor unifica y utiliza todos los contenidos para que el usuario pueda crear y modificar escenas, que son piezas fundamentales de cualquier aplicación. El visor de escenas controla y organiza las entidades asociadas a la escena, así como los componentes, comportamientos y dibujables asociados a cada entidad. Estas entidades pueden agruparse de forma jerárquica, lo que permite una organización fácil y lógica, y además incluye la posibilidad de filtrar las entidades por nombre dentro del árbol. El visor permite modificar directamente la vista previa de todas las entidades a través de los llamados manipuladores (traslación, rotación, escala) y al igual que los programas de diseño 3D y CAD, todos estos cambios se reflejan inmediatamente en la escena.

Nuevo Editor de Efectos

Uno de los puntos débiles de Wave Engine 2.x era la creación de materiales propios. Aunque esto era posible, requería un proceso completamente manual y muy tedioso. En Wave Engine 3.0 se ha creado un nuevo editor de efectos que te permite escribir tus propios efectos que luego puedes utilizar como materiales en tus escenas.

Este editor permite escribir tus propios shaders y agruparlos en efectos. Estos shaders serán definidos en HLSL (DirectX) con los metadatos propios del motor que facilitan el paso de los parámetros y la integración con el sistema. A la hora de definir los shaders, el editor dispone de resaltado de sintaxis, Intellisense, compilación automática, así como resaltado de errores en el propio código para facilitar al usuario su creación y definición.

Los shaders se componen de 2 bloques:

  • Diseño de recursos: Donde se define la lista de parámetros que recibirá el shader.
  • Colección de pases: Una lista de pases que se integra perfectamente con el nuevo sistema de Render en el que se puede definir su propio Render Pipeline, así como los pases que deben tener los materiales definidos.

También dispone de un visor 3D donde se compila y ejecuta en tiempo real el shader que se está definiendo. Y de forma dinámica, permite la prueba de pasar diferentes valores para todos los parámetros que hayas definido en la sección de recursos Layout, lo que consigue una edición totalmente interactiva.

Los efectos se componen de múltiples sombreadores, que se pueden definir a partir de directivas de compilación. El nuevo editor de efectos permite definir sus propias directivas de compilación y compilar y visualizar los diferentes sombreadores generados tras la activación de unas u otras directivas de compilación.

Además, cuando creas efectos muy complejos que tienen miles de shaders resultantes de la definición de múltiples directivas de compilación, se incluye un analizador que compila todas las combinaciones posibles de tu efecto indicando como resultado si todas las combinaciones se han compilado con éxito o de lo contrario, qué combinaciones no se han compilado, permitiéndote navegar hasta ellas y reparar los errores que contienen.

Una vez escrito tu shader, se traduce automáticamente a cada uno de los lenguajes utilizados en las diferentes tecnologías gráficas (OpenGL/ES, Metal, Vulkan). Para poder depurar este proceso automático, el editor incluye un visor que permite comprobar cuáles son las traducciones realizadas de tu shader a cada idioma.

Por último, el editor es capaz de generar automáticamente el activo del efecto, así como añadir un material decorador (clase c#) a la solución del usuario que permite gestionar la creación de dicho material desde el código de forma muy cómoda, así como la asignación de parámetros al efecto, facilitando todas estas tareas al usuario.

Preparado para la RX

RX (Extended Reality), es un término que engloba aplicaciones como la Realidad Virtual (RV), la Realidad Mixta (RM) o la Realidad Aumentada (RA).

Wave Engine 3.0 ha sido diseñado pensando en la RX.

Renderizado Estereoscópico de una sola pasada (instanciado)

El renderizado en una aplicación RX suele requerir dibujar la escena dos veces, una para el ojo izquierdo y otra para el derecho. Tradicionalmente cada imagen se renderiza en dos pasadas (una para cada ojo), por lo que el tiempo final se duplica.

En Wave Engine 3.0, el tiempo de renderizado se ha optimizado utilizando la técnica de Renderizado Estereoscópico de una sola pasada (instanciado). Así es como se desglosa:

  • Pase único: La escena se renderiza en una sola pasada, compartiendo gran parte del procesamiento entre cada ojo (culling, sorting, batching…)
  • Instancia: Cada objeto se renderiza dos veces utilizando una única DrawCall mediante Instancing. Además, cada instancia se dibuja en su textura correspondiente (ojo izquierdo o derecho). De esta manera, se comparte una gran cantidad de procesamiento para cada elemento (vinculación de parámetros de material, actualización de buffers de material, etc…).
  • Renderizado estéreo: El resultado es una imagen estéreo (TextureArray2D), que se proporcionará a los auriculares para que puedan presentar cada ojo de forma independiente.

Todos los efectos proporcionados por defecto en Wave Engine 3.0 soportan el renderizado estéreo de una sola pasada. Además, con el nuevo editor de efectos, es fácil desarrollar un efecto que lo soporte.

Como resultado, y junto con las mejoras introducidas en el RenderPipeline, se ha conseguido una increíble mejora del rendimiento, que puede aumentar la complejidad de nuestras escenas.

RXPlatform

Con la retroalimentación obtenida al desarrollar aplicaciones RX con versiones anteriores de WaveEngine, se han reimplementado todos los componentes y servicios ofrecidos a los usuarios para simplificar al máximo el desarrollo.

XRPlatform es el Servicio Base que gestiona toda la comunicación con la plataforma RX en cuestión. Cada plataforma en cuestión se proporcionará a través de la implementación de ese servicio (MixedRealityPlatform, OpenVRPlatform, etc…). Puntos a tener en cuenta:

Se ha eliminado el antiguo componente CameraRig. En WaveEngine 3.0 sólo necesitas una Camera3D en tu escena, sin ningún componente adicional. El servicio RXPlatform se encargará de hacer que esta cámara se renderice en estéreo en los auriculares.

RXPlatform expone diferentes propiedades que permiten acceder a diferentes áreas interesantes, en caso de que la implementación subyacente lo soporte:

  • InputTracking: Encargada de proporcionar el posicionamiento y estado de cada uno de los dispositivos de la plataforma XR (controladores, estaciones base, manos, auriculares…).
  • GestureInput: Ofrece acceso a gestos espaciales complejos en aquellas plataformas que lo soportan (HoloLens y HoloLens 2).
  • RenderableModels: Es posible obtener modelos 3D de diferentes dispositivos.
  • SpatialMapping: Proporciona una malla dinámica del entorno en el que se encuentra el dispositivo (HoloLens, HoloLens 2, Magic Leap, ARKit, ARCore).
  • SpatialAnchorStore: Permite añadir Spatial Anchors en el espacio y almacenarlos para recuperarlos en la siguiente sesión.

Nuevo Pipeline de Renderizado Extensible

En Wave Engine 3.0, la forma en que los objetos de una escena (mallas, sprites, luces, etc…) son procesados y representados en pantalla puede adaptarse a las necesidades de nuestra aplicación.

Un render pipeline es un elemento fundamental en Wave Engine 3.0, que se encarga de controlar todo el proceso de renderizado de la escena (clasificación, culling, pases, etc…). Por defecto, se proporciona un RenderPipeline, que implementa todas las funciones necesarias para su correcto funcionamiento, llamado DefaultRenderPipeline.

Sin embargo, ahora los usuarios tienen la posibilidad de proporcionar una implementación personalizada del render pipeline que se ajuste a sus necesidades. La implementación de nuestro RenderPipeline personalizado nos da una mayor granularidad y personalización, permitiéndonos eliminar procesos innecesarios o añadir tareas no contempladas anteriormente.

Cada escena tiene un render pipeline asociado, que se encarga de:

Recoger todos los elementos necesarios para renderizar la escena:

  • Luces: Luces de nuestra escena (DirectionalLight, PointLight y SpotLight)
  • Cámaras: La lista de cámaras de nuestra escena.
  • RenderObjects: Cualquier objeto que necesite ser renderizado, pueden ser mallas, sprites, billboards, líneas, etc.

Preparando los elementos a renderizar para cada cámara:

  • Culling: Renderizar sólo aquellos objetos que son visibles por la cámara.
  • Clasificación: Ordenar los objetos para un renderizado óptimo.
  • Batching: Agrupación de los objetos a pintar para minimizar el número de llamadas a dibujo, y así mejorar el rendimiento reduciendo el consumo de CPU.

Renderizando los elementos de la escena ya procesados. Para ello, un pipeline de renderizado ofrece diferentes modos de renderizado, llamados RenderPath. Un RenderPath se encarga de:

Gestionar cómo se procesará la iluminación. (Adelante, Luz-Prepaso, etc…)

  • Exponiendo propiedades y texturas que pueden ser inyectadas automáticamente en los materiales.
  • Definiendo una serie de pases necesarios para pintar en la escena y ejecutarlos secuencialmente para obtener el resultado final.
  • Cada pase afecta a la llamada de dibujo de un objeto. Para ello, el material del objeto debe ofrecer una implementación para cada pase. De lo contrario, el objeto no se renderizará.

Ahora, también es posible implementar nuestro propio RenderPath totalmente personalizado, y grabarlo en nuestro pipeline de renderizado, para que nuestros efectos y materiales puedan utilizarlo en la escena.

El nuevo ciclo de vida de las entidades

Wave Engine 3.0 ha redefinido, simplificado y estandarizado el funcionamiento de las entidades, los componentes, los servicios y los gestores de escena, permitiendo adjuntarlos, habilitarlos, deshabilitarlos y separarlos. También mantiene el antiguo inyector de dependencias y lo mejora.

Diagrama del ciclo de vida de los componentes

El nuevo ciclo de vida de los componentes se explica en el siguiente diagrama:

Controlamos el comportamiento de nuestro componente implementando estos métodos:

OnLoaded()

  • Llamado cuando el componente ha sido deserializado.
  • Se llama sólo una vez durante el ciclo de vida del componente.
  • Se utiliza para inicializar todas las variables y propiedades que no dependen de componentes externos.

OnAttached()

  • Invocada cuando el componente ha sido añadido a una entidad, o cuando la entidad asociada cambia de padre.
  • Todas las dependencias de este componente han sido resueltas. Sin embargo, es posible que no se hayan inicializado (pueden estar en estado desvinculado).
  • Este método puede utilizarse para establecer relaciones con otros elementos de la escena.

OnActivated()

  • Este método se llama cuando se activa un componente (su propiedad IsEnabled es verdadera).
  • Se llama durante el inicio si el componente está activado por defecto.
  • Este método se utiliza para realizar todas las tareas que queremos realizar cuando la entidad se activa.

OnDeactivated()

  • Invocado cuando un componente activado se desactiva (la propiedad IsEnabled es falsa).
  • Método utilizado para realizar todos los cambios necesarios para preparar el componente para un estado desactivado.

OnDetached()

  • Método invocado cuando el componente es retirado de su entidad propietaria. También se invoca cuando la entidad propietaria se retira del método utilizado principalmente para eliminar todas las referencias externas.

OnDestroy()

  • Se invoca cuando se destruye el componente.
  • Se llama sólo una vez. Una vez eliminado, el componente no puede volver a utilizarse.
  • Este método se utiliza para eliminar todos los recursos asociados a este componente.

Vinculación de elementos

También hemos redefinido la forma en que se inyectan las dependencias en el componente. Todas las dependencias se resuelven antes de adjuntar el componente.

Wave Engine 3.0 permite estos atributos como enlaces de elementos:

  • BindComponent: Inyecta un componente de la misma entidad de un tipo especificado..
  • BindEntity: Inyecta una referencia de entidad por su etiqueta.
  • BindService: Inyecta un servicio de la aplicación Wave de un tipo especificado..
  • BindSceneManager: Inyecta un gestor de escena de un tipo especificado.

Nuevo Soporte para Proyectos Web

Desde las primeras versiones de Wave Engine, hemos cubierto la mayoría de los dispositivos principales: teléfonos, tabletas, ordenadores de sobremesa, auriculares, etc. Sin embargo, la Web simplemente no era accesible. El estado de la técnica con .NET no permitía una solución factible para construir un puente entre el navegador y nuestro código C#.

Recibimos con una cálida bienvenida el nacimiento de WebGL (allá por 2011), basado en la especificación OpenGL ES, consumido a través de JavaScript. Dado que OpenGL ES ha sido nuestra API de dibujo en Android e iOS desde el principio, nos hizo pensar en una buena elección.

En 2015, ya probamos algunos intentos con JSIL, que transforma IL en JavaScript, pero acabamos cancelando ese camino: éramos capaces de ejecutar cálculos de matrices en JavaScript con un pequeño esfuerzo, pero el pegamento necesario para el dibujo era enorme y, al final, no aseguraba el rendimiento necesario.

La fuerte forma que está tomando WebAssembly últimamente y los esfuerzos realizados por Mono para ejecutar el CLR sobre él nos ha abierto una nueva ventana para pensar seriamente en llevar las aplicaciones de Wave Engine 3.0 a la Web.

A finales de 2018, empezó a ser posible ejecutar librerías .NET Standard en el navegador. Al mismo tiempo, Uno’s Wasm bootstrap NuGet nos permitió saltar rápidamente a nuestras primeras pruebas consumiendo WebGL.

Como se ha explicado anteriormente, Wave Engine 3.0 se basa en bibliotecas de bajo nivel para renderizar realmente en cada plataforma, por lo que necesitábamos un pegamento para hacer coincidir nuestro código C# con las huellas JavaScript de WebGL. También decidimos liberar este componente, WebGL.NET, como una pieza separada de Wave Engine. Aunque empezamos con soporte para WebGL 1, rápidamente pasamos a la v2 debido a la arquitectura de Wave Engine 3.0, pensada para aportar lo mejor de las últimas API de dibujo.

Actualmente, nuestro análisis de rendimiento proviene de la ejecución de nuestras muestras bajo diferentes escenarios: navegadores mezclados junto con dispositivos. Sin embargo, todavía no hemos estresado el tiempo de ejecución habilitando JIT o AOT: actualmente, IL es puramente interpretado. Al mismo tiempo, Mono sigue trabajando en su herramienta Wasm, mejorando principalmente el rendimiento.

Todo esto hace que creamos que esta ruta es lo suficientemente buena como para seguir invirtiendo en ella, seguido de los pasos que WebAssembly mismo está ganando con el tiempo -como ser capaz de ejecutarlo fuera del navegador, o habilitar escenarios multihilo.

Ya hemos empezado a jugar con las primeras aplicaciones de Wave Engine 3.0 para la web con esta tecnología y esperamos poder lanzarlas en breve, aunque no hay ninguna estimación al respecto.

Nuevo sistema de serialización basado en yaml

Wave Engine 3.0 ha decidido tener más control sobre cómo se almacenan y editan las entidades y componentes de la escena. Por eso hemos decidido dejar atrás la serialización XML DataContract y adoptar plenamente la serialización SharpYaml, más ligera y personalizable. Este cambio nos hizo mejorar en algunas características clave como:

Legibilidad

La misma escena que el archivo YAML tiende a ser más legible, también utilizando menos espacio que la versión XML DataContract.

Control de errores

Ahora tenemos un control de errores mucho más profundo de la escena. La escena es deserializada incluso si son componentes de tipo desconocido. Esto es importante durante el desarrollo porque podemos seguir editando la escena Wave incluso cuando hay problemas al deserializar su componente en la aplicación.

Personalización

La fácil personalización del progreso de la serialización nos permite personalizar la forma en que se serializan algunos tipos específicos. Esto es crucial porque de esta manera la escena detecta todas las referencias de los activos e inyecta su Id. Esto permite sólo declarar propiedades del tipo base (Textura, Modelo, etc), en lugar de declarar variables de su ruta.

Miembros serializados por defecto

Ahora todas las propiedades son serializadas excepto las propiedades marcadas con el atributo WaveIgnore. De esta forma crear nuevos componentes por código es mucho más sencillo porque no tenemos que crear todos sus atributos DataContract y DataMember.

Lo mejor está por llegar

Este es el primer paso dado para mejorar la calidad general deseada para WaveEngine 3.0. Sin embargo, queremos seguir personalizando el proceso de serialización/deserialización y ser mucho más flexibles.

Nuevo soporte para HoloLens 2.0

Hemos estado trabajando con Microsoft para dar soporte a todas las novedades que trae este dispositivo, lo que supone una gran evolución en la interacción respecto a la primera versión.

En esta segunda versión ahora tenemos soporte de seguimiento de manos para ambas manos con 21 puntos de seguimiento, esto permitirá a los usuarios interactuar de una manera más natural con los elementos 3D sin necesidad de aprender ciertos gestos para utilizar las aplicaciones. La nueva API proporciona información individual para cada dedo que puede ser utilizada en las nuevas interfaces para dar una forma más ágil de introducir datos.

También incluye una nueva API de seguimiento ocular que permitirá a los desarrolladores saber no sólo en qué dirección apunta la cabeza del usuario, sino también la distancia entre los ojos y hacia dónde apunta cada uno de ellos en todo momento.

También se ha mejorado la API de seguimiento del entorno que ayudará a representar los entornos con una mayor precisión, pudiendo generar oclusiones de objetos en 3D más realistas o incluso utilizar estas representaciones como parte útil de la app.

Este nuevo dispositivo tiene un cambio importante en su arquitectura ya que las HoloLens 1 corrían sobre arquitectura x86 mientras que la nueva versión corre sobre ARM64. Dado que WaveEngine 3.0 ya utiliza el nuevo runtime .NetCore 3.0 es capaz de traducir las instrucciones nativas a esta nueva arquitectura, aprovechando así el dispositivo.

Hoy se libera una preview de Wave Engine 3.0 que solo tiene soporte para crear proyectos en Windows, UWP y HoloLens.  Durante las próximas semanas, seguiremos generando nuevas versiones para liberar todo el trabajo realizado. ¡Estad atentos!

Javier Cantón
Autor
Javier Cantón
Plain Concepts Research