Nerf Unity for Oculus Quest 2 es un proyecto basado en el código de kwea123/nerf_Unity, que utiliza una técnica de renderizado volumetrico para visualizar imagenes3D generadas en Nerf dentro de Unity. Esta versión incluye soporte para el casco de realidad virtual Oculus Quest 2 y agrega nuevas herramientas para importar datos de volumen en secuencias png. El proyecto incluye diferentes escenas para mostrar las diferentes formas de utilizar esta técnica de renderizado, como renderizar modelos 3D y volúmenes. El proyecto requiere Unity 2022.2.1f1 y assets adicionales descargados e importados en Unity para su uso. Además, incluye dos shaders personalizados: uno antiguo (VolumeShad2) y uno nuevo (VolumeColorRenderingShader) para el renderizado de volúmenes.
¿Te imaginas poder crear objetos 3D realistas a partir de fotos 2D? Eso es lo que hace la IA de Nerf, una técnica de renderizado neural que utiliza redes neuronales para representar y renderizar escenas 3D basadas en una colección de imágenes 2D. La IA de Nerf puede rellenar los huecos y corregir los errores humanos al capturar las fotos.
En este artículo te voy a contar cómo surgió la idea de este proyecto, qué es Nerf y cómo se diferencia de la fotogrametría, y qué puedes hacer con este proyecto si te interesa probarlo.
Neural Radiance Field (NeRF) es una técnica de renderizado neural que utiliza redes neuronales para representar y renderizar escenas 3D basadas en una colección de imágenes 2D. Usando solo un número limitado de imágenes 2D de esas escenas. La red neuronal aprende a representar la escena como una función que relaciona la posición y la dirección de la cámara con el color y la transparencia de cada punto en el espacio. Usando esta función, la red neuronal puede crear nuevas imágenes de la escena desde cualquier ángulo o distancia
La diferencia principal entre la IA de Nerf y la fotogrametría es que la primera usa redes neuronales para generar las escenas 3D, mientras que la segunda usa algoritmos geométricos para reconstruir las escenas a partir de las fotos. La ventaja de la IA de Nerf es que puede producir resultados más realistas y detallados con menos datos, además es capaz de generar una escena en muy poco tiempo, simpre teniendo en cuenta que aprovecha las capacidades de las potentes tarjetas gráficas actuales.
Me interesé por la IA de Nerf cuando vi los impresionantes resultados que se podían obtener con esta técnica, como generar objetos 3D realistas a partir de fotos 2D. Me pareció una forma muy innovadora y potente de crear contenido 3D sin necesidad de usar cámaras especiales o escáneres.
Sin embargo, me di cuenta de que no había una forma fácil y accesible de usar la IA de Nerf en realidad virtual (VR), Por eso decidí crear el proyecto Nerf Unity para Oculus Quest 2, un fork del proyecto kwea123/nerf_Unity que adapta el código original para funcionar con el casco VR Oculus Quest 2. El Oculus Quest 2 es uno de los cascos VR más populares y asequibles del mercado, que ofrece una gran calidad gráfica y una experiencia inalámbrica.
El proyecto incluye un nuevo shader y herramientas para importar datos volumétricos en 3D desde secuencias png. El shader se basa en el renderizado volumétrico usando raymarching, que es una técnica que simula el comportamiento de la luz al atravesar un medio con diferentes densidades y propiedades ópticas . En lugar de calcular las intersecciones directas entre los rayos de luz y los objetos 3D, el raymarching avanza los rayos en pequeños pasos y evalúa la función de distancia más cercana a cada paso . Esto permite renderizar escenas complejas y realistas con efectos como sombras suaves, refracción y transparencia.
Realmente lo más interesante del proyecto es el Shader que he creado, combinando cosas del shader del proyecto unity-volume-rendering y de kwea123/nerf_Unity . El sombreador usa una textura 3D (_DataTex) y genera un raymarch a través de la textura para producir el renderizado volumétrico. El sombreador tiene varias propiedades que se pueden ajustar para personalizar el resultado del renderizado, como los valores mínimo y máximo (_MinVal, _MaxVal), la transición y el factor de alfa (_alphaTransition, _alphaFactor), el factor de profundidad (_deptFactor), la iluminación y el factor de luz (_lighting, _lightFactor), y el ruido y el factor de ruido (_Noise, _noiseFactor).
El código se divide en varias partes:
- La parte de Properties define las variables que se pueden modificar desde fuera del código, como el número de iteraciones, la textura 3D de datos (_DataTex), los valores mínimo y máximo, los rangos para x, y y z, y otros parámetros.
- La parte de SubShader define las etiquetas para renderizar el objeto transparente, y establece el LOD (nivel de detalle), Cull (eliminación de caras ocultas), ZTest (prueba de profundidad), ZWrite (escritura de profundidad) y Blend (mezcla de colores).
- La parte de Pass define los sombreadores de vértice y fragmento (vertex shader y fragment shader), incluyendo las estructuras de entrada y salida, así como las variables uniformes para las texturas 3D y 2D, la iluminación, el número de iteraciones y el ruido.
- La parte del RayInfo define la estructura que almacena la información del rayo que atraviesa la textura. También se definen las funciones intersectAABB (que calcula las intersecciones del rayo con una caja alineada con los ejes), getRayBack2Front (que devuelve la dirección e inicio del rayo para un vértice dado) y getViewRayDir (que calcula la dirección del rayo desde la cámara).
- La parte principal son las funciones vertex shader y fragment shader. La función vertex shader simplemente devuelve la posición del vértice en pantalla y su coordenada en la textura 3D. La función fragment shader realiza el raymarch a través de la textura volumétrica, muestreando la textura en cada paso e acumulando el color y alfa. También aplica efectos de iluminación y ruido según las propiedades del sombreador. Finalmente devuelve el color resultante.
Puedes ver el proyecto en mi Github