'Gaussian splatting' es bastante genial
(aras-p.info)- El artículo de 3D Gaussian Splatting de SIGGRAPH 2023 propone convertir escenas basadas en fotografías en millones de gaussianas 3D y renderizarlas en tiempo real, y también se publicó una implementación experimental de visualización en Unity
- La escena se representa como un conjunto de blobs en el espacio con posición, rotación, escala no uniforme, opacidad y coeficientes de armónicos esféricos, en lugar de mallas, vóxeles o campos de distancia
- Este método no es NeRF, y la implementación oficial tampoco usa un pipeline de rasterización de función fija, sino renderizado por software en mosaicos 100% basado en CUDA
- La implementación en Unity tarda 23.8 ms en una NVIDIA RTX 3080 Ti a 1200x800, más lenta que los 7.40 ms del visor oficial, pero está escrita en HLSL estándar y también funciona en Mac
- La escena bicycle ocupa 1.5 GB en disco, cerca de 6 millones de blobs y unos 250 bytes por blob, así que además del rendimiento, el tamaño de los datos y la memoria GPU también son objetivos importantes de mejora
El artículo de SIGGRAPH 2023 y el experimento en Unity
- El artículo de SIGGRAPH 2023 3D Gaussian Splatting for Real-Time Radiance Field Rendering es un trabajo de Kerbl, Kopanas, Leimkühler y Drettakis
- El sitio web del artículo, el código fuente y el dataset están disponibles públicamente, así que se puede intentar experimentar y reproducirlo directamente
- El experimento en Unity se enfoca en recibir un archivo de “modelo” Gaussian Splat ya generado para visualizarlo en tiempo real
- La implementación está publicada en aras-p/UnityGaussianSplatting y se planean más experimentos después
- También interesa saber si se puede reducir el tamaño de los datos, posiblemente aprovechando experimentos previos de compresión de float
De qué está compuesto un Gaussian Splat
- Gaussian Splatting representa una escena 3D como millones de partículas en lugar de una malla poligonal, vóxeles o campos de distancia
- Cada partícula, es decir, cada “3D Gaussian”, tiene la siguiente información
- Posición en el espacio 3D
- Rotación
- Escala 3D no uniforme
- Opacidad
- Información de color
- El color no se expresa como un color único, sino como coeficientes de Spherical Harmonics de tercer orden, por lo que puede variar según la dirección de vista
- Al renderizar, la partícula no se dibuja como una esfera 3D alargada, sino que se “splatea” como una gaussiana 2D en el espacio de pantalla
- La idea clave es construir una representación de una escena basada en fotografías como un conjunto de blobs con escala y color, y renderizarla rápidamente
No es NeRF ni rasterización de función fija
- Gaussian Splatting no es NeRF
- Se indica explícitamente que no tiene un componente “neural”
- Y la razón de su velocidad tampoco es “porque usa hardware de rasterización GPU”
- La implementación oficial no usa un pipeline de rasterización
- Está implementada 100% en CUDA
- El rendimiento de la implementación oficial no proviene de rasterización de función fija, sino de renderizado por software basado en mosaicos que procesa eficientemente millones de partículas escaladas
- Aun así, un rasterizador por software “sobre la GPU” basado en mosaicos no es una idea completamente nueva
Conexión con bloques tecnológicos antiguos
- Gaussian Splatting en sí se conecta con trabajos de 2001~2002 como EWA Splatting
- Se colocan blobs escalados y orientados en el espacio, se calcula cómo se proyectan en pantalla y luego se procesa una forma gaussiana en espacio de pantalla
- El juego de 1994 Ecstatica es un caso singular que usó un renderizador basado en elipsoides
- Spherical Harmonics se han usado durante siglos en física, y en gráficos por computadora se hicieron ampliamente conocidos alrededor del año 2000 gracias a trabajos de Ravi Ramamoorthi y Peter-Pike Sloan
- Ray tracing volume densities de Kajiya & Von Herzen en 1984 podría ser un caso temprano de uso en gráficos
- Se puede ver un resumen relacionado en Patapom’s page
- Point-Based Rendering también es un campo antiguo
- Los sistemas de partículas se han usado desde hace mucho en VFX y para representar fenómenos no sólidos
- The Use of Points as a Display Primitive es un trabajo de 1985
- Surfels es un artículo de 2000
- La demoscene y las herramientas de VFX en tiempo real también han usado enfoques de renderizado no tradicionales
- Ejemplos: Fairlight & CNCD con Agenda Circling Forth, Ceasefire (all falls down..), Number One / Another One
- Notch es una herramienta de VFX en tiempo real con funciones para crear, simular y mostrar objetos basados en puntos y blobs
- fogleman/primitive es un ejemplo de herramienta de 2016 que representa imágenes como conjuntos de formas primitivas
- “Dreams” de Media Molecule usó un renderizador basado en splats, y su versión lanzada parece combinar varias técnicas
- La charla “Learning from Failure” de Alex Evans puede verse en SIGGRAPH 2015 y Umbra Ignite 2015
- La rasterización en mosaicos para partículas existe al menos desde 2014 con Holy smoke! Faster Particle Rendering using Direct Compute de Gareth Thomas
- Dividir la pantalla en mosaicos y trabajar dentro de cada mosaico puede reducir el tráfico de memoria
- Este enfoque también se relaciona con cómo funcionan muchas GPU móviles, y se remonta a diseños tempranos como PowerVR en 1996 y Pixel Planes 5 en 1989
Estado actual de UnityGaussianSplatting
- aras-p/UnityGaussianSplatting es una implementación de visor para modelos Gaussian Splat
- Su estado actual está más cerca de “funciona, pero no es rápido”
- En una NVIDIA RTX 3080 Ti, al renderizar la escena bicycle a 1200x800, la diferencia de rendimiento es grande
- Visor oficial: 7.40 ms, 135 FPS
- Implementación en Unity: 23.8 ms, 42 FPS
- Aproximadamente 4 veces más lento
- El método de ordenamiento también influye en la diferencia de rendimiento
- La implementación de Unity usa un GPU bitonic sort relativamente simple
- La implementación oficial usa CUDA radix sort basado en el algoritmo OneSweep
- El enfoque de rasterización también es distinto
- La implementación oficial usa un método basado en mosaicos escrito en CUDA
- La implementación de Unity renderiza cada splat como un quad en espacio de pantalla usando el pipeline general de rasterización GPU
- La implementación de Unity tiene ventajas en portabilidad
- El código está escrito en HLSL estándar dentro de Unity, por lo que también funciona en Mac
- En un Apple M1 Max, la misma escena se renderiza en 108 ms y 9 FPS
- La memoria GPU parece ser menor en la implementación actual de Unity
- Visor oficial: 4.8 GB
- Implementación en Unity: 2.2 GB
- Estas cifras incluyen también la memoria usada por Unity Editor
Tamaño de los datos y uso de memoria
- Las discusiones sobre Gaussian Splatting suelen enfocarse en la calidad y la velocidad de renderizado, pero el tamaño de los datos y el uso de memoria también son problemas importantes
- La escena bicycle ocupa 1.5 GB en disco
- Esa escena está compuesta por cerca de 6 millones de blobs
- Cada blob usa aproximadamente 250 bytes
- En tiempo de ejecución se necesita memoria adicional para ordenamiento, renderizado en mosaicos y otras tareas
- La presentación de Dreams incluye ideas que podrían servir como referencia para reducir el tamaño
1 comentarios
Opiniones en Hacker News
La expresión de que se evitó lo “neural” aunque se usan descenso de gradiente y renderizado diferenciable suena un poco presumida.
Conceptualmente, de forma similar a NeRF, se optimiza una representación basada en datos que aproxima variables relacionadas con una escena 3D a partir de imágenes; la diferencia parece ser que NeRF modela el campo de radiancia, es decir, la función completa de transporte de luz, mientras que aquí solo se modelan las condiciones de borde donde llega la luz.
Como el objetivo es distinto, una base de representación más simple tiene sentido y los resultados se ven bien, pero me da pena que se presente como si evitar redes neuronales fuera algo digno de elogio en sí mismo. Las redes neuronales no se usan solo porque estén de moda; realmente son aproximadores de funciones potentes, y el abanico de estructuras a las que llamamos “redes neuronales” es muy amplio.
Es solo la impresión que me dio el tono de la introducción del blog, así que podría no coincidir con el paper en sí.
Por eso parece más fácil de entender y también más fácil de integrar con otro software 3D, como editores o renderers, y parece que también permitiría animación. Un aproximador de funciones de caja negra que representa toda la escena de una vez no se siente escalable ni elegante.
Dicho eso, incluso cuando las redes neuronales modelan bien un problema, muchas veces no sabemos cómo funciona realmente el modelo entrenado, y sus requisitos de datos y el reentrenamiento iterativo limitan su utilidad para construir soluciones de largo plazo.
En este caso prefiero interpretarlo de buena fe: los autores no estaban avivando una pequeña guerra cultural, sino haciendo un chiste amigable.
Cada píxel renderizado es una suma ponderada de las contribuciones de gaussianas dependientes del punto de vista y sin límites definidos, así que no es correcta la distinción de que NeRF modela un campo de radiancia y esto solo modela condiciones de borde.
Si además se considera que NeRF ha usado representaciones de armónicos esféricos de bajo rango para el dominio direccional, queda casi como 3D+α, y surge la pregunta de por qué elegir una red neuronal para reconstruir una función de tan baja dimensionalidad.
En inferencia, para cada píxel hay que muestrear repetidamente la red neuronal a lo largo del rayo de visión, pero las representaciones comprimidas de campos de luz son un problema que en gráficos ya se trabaja desde hace mucho, así que esa parte se siente bastante rara.
Más tarde, Plenoxels quitó el “Ne” de NeRF y mejoró mucho el rendimiento de entrenamiento e inferencia, y Instant NeRF de Nvidia lo compensó en cierta medida interpolando embeddings de entrada sofisticados dentro de una red neuronal pequeña: https://nvlabs.github.io/instant-ngp/assets/mueller2022insta...
En ingeniería gráfica, donde más se han usado redes neuronales es sobre todo en reconstrucción de datos escasos, especialmente reducción de ruido, y eso es natural porque es un problema de alta dimensionalidad. Aun así, rara vez superan de forma contundente a los algoritmos hechos a mano, aunque el uso de redes neuronales pequeñas para compresión parece tener futuro.
En gráficos hay mucha aproximación de funciones, así que hay espacio para redes neuronales, pero las funciones que se manejan suelen ser más comprensibles y controlables, a diferencia de áreas como la comprensión del lenguaje natural, donde es casi imposible usar soluciones algorítmicas hechas a mano.
Muchas conversaciones terminan en IA=malo, CRYPTO=malo; el problema no es que la postura contraria sea necesariamente incorrecta, sino que si uno decide primero la conclusión y deja de pensar, no tiene forma de darse cuenta de si sus propias ideas son completamente disparatadas.
Es un trabajo realmente genial.
En el artículo se mencionan el renderizado basado en puntos y los sistemas de partículas, y en los juegos recientes se siente un cambio sutil hacia un nuevo estilo de partículas, más orientado a puntos que a fragmentos de textura, pero que se comporta como un sistema físico.
Por ejemplo, están Hogwarts: https://www.gamespot.com/a/uploads/original/1816/18167535/40..., Forspoken: https://oyster.ignimgs.com/mediawiki/apis.ign.com/project-at..., Starfield: https://dotesports.com/wp-content/uploads/2023/08/temple-loc..., AC6 y FF16.
Lo que tienen en común es que se ven como partículas puntuales transparentes y de colores con física, y parece que se usan especialmente en consolas para lograr efectos baratos en la GPU sin cargar la CPU. Me da curiosidad si alguien del desarrollo de juegos sabe más al respecto.
Sin simulación de fluidos, un sistema de partículas basado en puntos se ve simplemente como fuegos artificiales. El siguiente paso fue que cada partícula tuviera física propia, como momento o viento, y se renderizara como un pequeño billboard con textura; hasta hace relativamente poco se usaba para representar explosiones o humo.
Ahora, con mejor rendimiento de las máquinas y mejores algoritmos de física, se pueden ejecutar en tiempo real simulaciones de fluidos en las que las partículas interactúan entre sí, y los efectos que se ven hoy parecen ir por ese lado.
En el mundo de los juegos 3D, trabajar solo con primitivas realmente 3D tiene muchas ventajas conceptuales y estructurales, y los sprites de puntos se pueden tratar casi como objetos 3D infinitamente pequeños.
En cambio, si se insertan sprites 2D en una escena 3D, cuando tienen transparencia parcial hay que ordenarlos de atrás hacia adelante, no encajan bien con el z-buffer, chocan con el orden de agrupación optimizado para la GPU, se incrustan en superficies 3D y tienden a revelar que son 2D.
Para resolver estos problemas se han ido acumulando muchos compromisos, como la transparencia tipo screen-door, shaders que cambian la forma de escribir en el z-buffer, alpha test, alpha-to-coverage, etc.
En VR, el renderizado basado en imágenes 2D dentro de una escena 3D resalta todavía peor que en una pantalla única, y se nota mucho más que son billboards planos. Si juntas todas estas razones, hay motivos de sobra para querer alejarse de los efectos con sprites de textura 2D en escenas 3D.
Por la tendencia de la IA, también parece tener cierta relación el hecho de que las GPU estén yendo hacia algo como “GPU de conjunto de instrucciones reducido dentro de la GPU”, con RT cores y Tensor cores.
Hace unos años NVIDIA escribió un kernel para llevar kernels SE(3) a Tensor cores, y no me sorprendería que parte de eso pueda portarse también a la compresión y la ejecución de la parte de armónicos esféricos del Gaussian splatting: https://developer.nvidia.com/blog/accelerating-se3-transform...
El Gaussian splatting siempre tiene una región de soporte en el espacio 3D, así que parece que podría ser bastante eficiente, y aunque se transforme de forma aproximada y rápida, el resultado final podría verse bastante bien.
También es relativamente fácil crear hermosos remolinos de puntos brillantes. Supongo que Unreal Engine tiene algo parecido, pero no tengo mucha experiencia directa.
No creo que haya surgido de ahí, pero esa demo es el primer hito que puedo señalar.
Cuando salió por primera vez el paper de SIGGRAPH, me entusiasmó muchísimo.
Durante los últimos 10 años, más o menos, he estado tomando fotos desde cientos de ángulos de las habitaciones en las que viví, con la idea de algún día recrearlas en 3D, y el Gaussian splatting es la primera técnica que siento que podría reproducirlas de una forma casi real.
Me emociona mucho pensar que, cuando las herramientas maduren más, podré volver a recorrer mis antiguas habitaciones y ponerme nostálgico.
No conozco bien el área, así que quizá sea una pregunta ignorante, pero estos videos se ven realmente geniales.
Según entiendo, la escena o el campo de radiancia siempre es estático y la iluminación está precalculada; me pregunto si existe la posibilidad de que evolucione hacia cambiar dinámicamente la iluminación y soportar también movimiento.
En un campo de radiancia no hay conceptos como emisión, reflexión o absorción de luz; todo queda reducido a un único valor de “luz transmitida”. En ese sentido, un campo de radiancia se parece más a una foto 3D.
Para cambiar eso habría que estimar la posición de las fuentes de luz, las superficies, los materiales, etc., mediante renderizado inverso o fotogrametría, y luego volver a usar trazado de trayectorias tradicional.
Otra dirección posible no es la animación sino el video: capturar continuamente el campo de radiancia a lo largo del tiempo y comprimir las similitudes entre fotogramas para obtener coherencia temporal.
También se pueden encadenar varios para crear animaciones: https://twitter.com/8Infinite8/status/1699460316529090568
Para reiluminación hay muchas variantes de NeRF que la soportan, así que también parece posible optimizar los parámetros de material de los splats.
Por ejemplo, si en una escena interior una mesa proyecta una sombra oscura sobre el piso, NeRF todavía no entiende las fuentes de luz ni las sombras, así que no puede saber si el piso es negro, si es un piso blanco cubierto por la sombra de la mesa, o si hay un Stanford bunny azul escondido dentro de la sombra.
Los rigs de escaneo 3D que capturan objetos pequeños, como rostros humanos, lo resuelven manipulando la iluminación y muestreando directamente el BRDF. Si no se puede manipular la iluminación, quizá se pueda estimar el BRDF, pero con limitaciones.
Volver a agregar animación puede ser fácil, pero para capturar la animación en sí harían falta varias cámaras, o habría que depender de estimaciones, como una red neuronal que complete imaginando el lado opuesto porque se trata de una persona.
Intel hizo hace algunos años un proyecto en el que capturaba una escena con varias cámaras y permitía cambiar la posición de la cámara en posproducción; parecía apuntar a transmisiones de futbol americano, pero no escuché que se hubiera lanzado realmente. Se necesitan varias cámaras al estilo Matrix.
Es decir, hacer que los datos se animen según la hora del día. Los requisitos de datos pueden crecer, pero con métodos de interpolación quizá no sea tan malo.
Si una escena estática pesa 2 GB, creo que una aproximación razonable por horas del día podría hacerse con menos de 16 GB, y renderizarse en GPUs modernas. Después, es cuestión de pasar algunos años optimizando mientras esperamos que el rendimiento de nivel H100 llegue al mercado de consumo.
Siempre es divertido cuando la ciencia supera las expectativas de la ciencia ficción.
En este caso me vino de inmediato a la mente el concepto de Braindance de Cyberpunk 2077: la posibilidad de moverse dentro de los recuerdos visuales de otra persona, dentro del rango que esa persona percibió de la escena.
Cuando mueves la cámara a un lugar distinto del punto de vista original, el campo visual se desmorona como una masa de píxeles tridimensionales; es parecido al concepto de blob de aquí, pero sorprendentemente se ve mucho menos refinado que en este artículo.
https://steelseries.com/blog/how-to-braindance-cyberpunk-207...
El splatting en renderizado volumétrico es una técnica bastante antigua. Está el artículo de julio de 1991 de Westover, Lee Alan, “SPLATTING: A Parallel, Feed-Forward Volume Rendering Algorithm”.
Lo segundo no parece que nadie intente ocultarlo, y lo primero no parece correcto.
No sé de dónde salió esa intuición, pero en esa época vivía cerca de Boston y tenía hijos pequeños.
Espero con ganas la primera implementación WebGPU nativa y optimizada de renderizado 3DGS.
También me da curiosidad cómo se comprimirán y descomprimirán eficientemente los datos de la escena.
Dejé algunas notas sobre esta pregunta en un hilo de Zulip: https://xi.zulipchat.com/#narrow/stream/197075-gpu/topic/Gau...
Hace poco vi un video que muestra cómo usar Gaussian splatting: Getting Started With 3D Gaussian Splats for Windows (Beginner Guide) - https://www.youtube.com/watch?v=UXtuigy_wYc
Me intriga cuál es el estado del arte de la reconstrucción de estructura a partir del movimiento
Cuando hay un video de un espacio, quiero saber cómo se convierte realmente hoy en una escena 3D
Esa es justamente la entrada del proceso de reconstrucción de escena descrito en este paper
Hasta donde sé, el enfoque básico de SfM no ha cambiado mucho en la última década más o menos, y se resume en extracción de características de imagen como SIFT, emparejamiento heurístico, ajuste por paquetes y eliminación de valores atípicos
La fotogrametría común es la respuesta, y el interés y la utilidad práctica de los enfoques tipo NeRF también van creciendo poco a poco
Sin embargo, sorprende que no se preste más atención a las relaciones espaciales adicionales que pueden inferirse solo por el hecho de que sea video. Parece que la restricción de que la cámara solo puede moverse de ciertas maneras entre fotogramas podría usarse para estimar la pose de la cámara
Existe la idea de ejecutar marching cubes sobre las gaussianas splatteadas para extraer una malla, pero creo que todavía no he visto un caso real de eso
A fines de los 90 renderizábamos isosuperficies de vóxeles con blobs
Escaneábamos los vóxeles de superficie en todo el arreglo 3D de vóxeles, calculábamos las normales a partir del gradiente de densidad local y luego las cuantizábamos a una de 240
Después usábamos una tabla de vectores de desplazamiento para crear cadenas de vóxeles de superficie, y la mayoría de los vóxeles ocupaban 2 bytes: un índice de desplazamiento respecto del vóxel anterior y un índice de vector normal
La iluminación para los 240 vectores normales se precalculaba y se guardaba en una tabla de consulta, y el software podía pintar pequeños círculos de color en el z-buffer muy rápidamente
La gran pena en ese entonces era que no podíamos usar perspectiva. Como transformábamos los vectores de desplazamiento al espacio de pantalla en cada cuadro, era algo como pintar un blob, aplicar un offset, consultar el color y volver a pintar. Había un valor de desplazamiento que marcaba el final de la cadena y el almacenamiento de la siguiente posición absoluta, pero la mayoría de los vóxeles ocupaban 2 bytes