Nvidia Omniverse, qué es y por dónde empezar

Hace un tiempo que empecé a oír de esta plataforma y hace unos meses empecé a trastear con ella y ver que me podía ofrecerme profesionalmente. La verdad que me gustó lo que vi y además me percaté de la poca documentación que había (y la nula información técnica que hay de ella en castellano), por ese motivo me decidí a escribir esta entrada en el blog, para contar una pequeña introducción a Nvidia Omniverse.

Antes de empezar vamos a definir que es Omniverse, por que al ser una plataforma que puede utilizarse para múltiples tareas puede llevar a confusión. La definición que dan en la página web de Nvidia es:

NVIDIA Omniverse™, una plataforma ampliable basada en Universal Scene Description (USD), ayuda a hacerlo posible al permitir a personas y equipos crear canalizaciones 3D personalizadas y simular mundos virtuales a gran escala más rápido que nunca.

En esta definición podemos sacar 3 cosas en claro:

  1. Es una plataforma basada en Universal Scene Description (USD). USD es un formato de fichero creado por Pixar, que se utiliza para describir escenas tridimensionales. Es un formato preparado para guardar escenas tridimensionales completas y para este cometido está muy optimizado. He oído algunas personas referirse a él como el HTML del metaverso, esto hoy en día es una equivocación puesto que aunque puede contener modelos 3D complejos y grandes, la forma de renderizarse esos modelos dependerá del motor de renderizado en el que se visualice, no es lo mismo (ni los shaders son compatibles) utilizar un motor de renderizado por trazado de rayos (como pueden ser VRay, Arnold , Renderman, etc..) que renderizarlo con un motor de render de un motor de juego (Unity, Unreal, Godot, etc…), porque los Shaders que se utilizaran en los diferentes casos serán diferentes (ni si quiera entre motores tienen definidos los mismos shaders).
  2. Es una plataforma que permite crear canalizaciones 3D. Omniverse utiliza conectores para poder conectar diferentes herramientas con él y entre ellas, por ejemplo, tiene conectores para herramientas de modelado 3D (3DS Max, Maya, Adobe Substance), herramienta de diseño CAD (Revit, Archicad), Motores de juego (Unreal) y Simulación (Ipolog, kitWare). Esto permite tener un repositorio unificado, donde cualquier cambio que se haga sobre un activo puede repercutir en el resto de las herramientas que lo utilicen.
  3. Es una plataforma que permite simular mundos virtuales. Esto a mi parecer es uno de los puntos más fuertes de Omniverse, a parte de los conectores, proporciona una serie de aplicaciones y herramientas que permiten generar simulaciones realistas de cualquier tipo de situación. Esto permite poder simular físicas, aplicar modelos de Inteligencia artificial o renderizar la escena con acabados fotorrealista (el renderizado se realizar por medio de trazado de rayos por lo que Omniverse pide mínimo una tarjeta Nvidia RTX). Con estas herramientas más la posibilidad de tener conectores contra aplicaciones de CAD podemos crear gemelos digitales.

Ahora que he definido que es Omniverse podemos definir, según mi punto de vista, que no es Omniverse.

Omniverse no es un metaverso (o por lo menos no es un metaverso según la definición actual, ya que el metaverso aún no existe). Estoy de acuerdo que es una herramienta para crear el metaverso, pero por sí solo Omniverse no lo es. No lo es porque no es una aplicación masiva, no es social, aunque últimamente han añadido elementos de trabajo colaborativo, no está diseñado para el acceso a él por el gran público. Por todo esto yo no lo definiría como un metaverso, como si lo puede ser Horizon Worlds, Altspace o Decentraland.

En este tutorial no vamos a ver todas las aplicaciones que hay dentro de la plataforma, nos centraremos en utilizar Create y Code.

Omniverse Create es una aplicación que nos permite la creación y composición de escenas 3D, esto nos permite poder ensamblar simulaciones complejas en tiempo real, además la vista del renderizado será con trazado de rayos, lo que nos dará una visualización realista.

Con Omniverse Code podremos desarrollar extensiones, aplicaciones y microservicios. Para poder desarrollarlas utilizaremos el lenguaje de programación Python (también se puede desarrollar con C++, pero en este tutorial no lo utilizaremos). Todas las extensiones que se utilizan en Omniverse están desarrolladas en este lenguaje y Nvidia proporciona el código en la propia plataforma.

Una vez definido que es Omniverse y sus aplicaciones empezaremos a entrar en harina, lo que haremos en este tutorial será una extensión con Omniverse Code que nos permita poder generar modelos primitivos. Para poder empezar a desarrollar, lo primero que tendremos que hacer es descargar e instalar Omniverse. Una vez descargado nos pedirá un usuario, si no se tiene se tendrá que crear.

Una vez que la aplicación este abierta tendremos que seleccionar la pestaña intercambio como se puede ver en la imagen.

En ella seleccionamos Core y lo instalamos, después seleccionamos Create y lo instalamos. Una vez instaladas las dos aplicaciones lanzamos Code.

Cuando se haya abierto la aplicación, nos posicionaremos en la pestaña de Extensions, si no puede ver esta pestaña, habilítelo en Windows->Extensions.

En el panel Extensions pulse sobre el botón + y seleccione “New Extensions Template Project”. Después seleccione la ubicación donde va a querer guardar la extensión. Nos pedirá que le demos un nombre al proyecto, en este caso lo llamaremos “ext-spawn-prims” y un nombre de la extensión que llamaremos “omni.spawn_prims”.

Al terminar de crear la extensión se abrirá de forma automática el editor que tengamos para Phyton. En mi caso trabajaré con Visual Studio Code. Podéis ver que Code ha creado un proyecto completo con un montón de ficheros, no voy a entrar en que hace cada uno de estos ficheros, nos centraremos solamente en uno para el tutorial. El fichero que nos interesa estará en la ruta: .\ext-spawn-prims\exts\omni.spawn_prims\omni\spawn_prims\extension.py .

El código que se generará en el fichero será parecido a este:

Para empezar, cambiaremos el nombre de la ventana, para ello la línea 22 la cambiaremos a esta:

self._window = ui.Window("Spawn Primitives", width=300, height=300)

Eso hará que la ventana que se cree tenga el nombre “Spawn Primitives”. Ahora vamos a cambiar el label que tenemos puesto, para eso la línea 25 la cambiamos por esta:

ui.Label("Spawn Creator")

Ahora borraremos de la línea 28 hasta la 40 y añadiremos la siguiente línea después del label:

ui.Button("Spawn Cube")

Dejamos sin definir el evento click del botón, puesto que aún no tenemos desarrollado el método que se ejecutará.

El código tendrá que quedar de esta forma:

 

Y la ventana se tendrá que ver de esta forma:

Ahora desarrollaremos el método que se encargara de generar el cubo, para ello antes de la definición del botón añadiremos este método:

def on_create_cube():
print("[omni.spawn_prims] create cube")
omni.kit.commands.execute('CreateMeshPrimWithDefaultXform',prim_type='Cube')

Y la definición del botón la cambiaremos a lo siguiente:

ui.Button("Spawn Cube", clicked_fn=lambda: on_create_cube())

el código se quedará de esta manera:

 

Si probamos ahora la extensión en Omniverse pulsando el botón “Spawn Cube” se creará un cubo en medio de la escena. Podemos ampliar esto creando una extensión que pueda crear cualquier tipo básico de modelo, para ello primero cambiaremos el método on_create_cube para que pueda aceptar un parámetro que se lo pasaremos al método que ejecuta el comando, el código del método quedará de esta manera:

def on_create_cube(prim_type):
print("[omni.spawn_prims] create cube")            omni.kit.commands.execute('CreateMeshPrimWithDefaultXform',prim_type=prim_type)

Y además cambiaremos la llamada desde el callback del botón:

ui.Button("Spawn Cube", clicked_fn=lambda: on_create_cube('Cube'))

Ahora si queremos generar más de un tipo de modelo lo único que tenemos que hacer es añadir nuevos botones, uno para cada tipo de modelo:

ui.Button("Spawn Cone", clicked_fn=lambda: on_create_cube('Cone'))
ui.Button("Spawn Cylinder ", clicked_fn=lambda: on_create_cube(‘Cylinder’))

ui.Button("Spawn Sphere ", clicked_fn=lambda: on_create_cube(‘Sphere’))
ui.Button("Spawn Plane", clicked_fn=lambda: on_create_cube(‘Plane’))
ui.Button("Spawn'Disk", clicked_fn=lambda: on_create_cube('Disk'))

El resultado final quedaría algo parecido a las siguientes capturas:

 

Con esto tendremos hecho una pequeña extensión con la que podemos ver como empezar a dar los primeros pasos y la potencia que tiene la plataforma.

 

 

He leído y acepto la política de privacidad
Acepto recibir emails sobre actividades de recruiting NTT DATA