“Gaussian splatting” é bem legal
(aras-p.info)- O artigo 3D Gaussian Splatting da SIGGRAPH 2023 apresenta uma abordagem que cria cenas baseadas em fotos com milhões de Gaussianas 3D e as renderiza em tempo real; uma implementação experimental de visualização em Unity também foi publicada
- A cena é representada não por malhas, voxels ou campos de distância, mas por um conjunto de blobs no espaço, com posição, rotação, escala não uniforme, opacidade e coeficientes de harmônicos esféricos
- Esse método não é NeRF, e a implementação oficial também não usa um pipeline de rasterização de função fixa, mas sim renderização em software baseada em tiles, 100% em CUDA
- A implementação em Unity leva 23,8 ms em uma NVIDIA RTX 3080 Ti a 1200x800, mais lenta que os 7,40 ms do visualizador oficial, mas é escrita em HLSL comum e também funciona no Mac
- A cena bicycle ocupa 1,5 GB em disco, tem cerca de 6 milhões de blobs e consome cerca de 250 bytes por blob, fazendo com que não só o desempenho, mas também o tamanho dos dados e a memória da GPU sejam alvos importantes de melhoria
Artigo da SIGGRAPH 2023 e experimento em Unity
- O artigo da SIGGRAPH 2023 3D Gaussian Splatting for Real-Time Radiance Field Rendering é um trabalho de Kerbl, Kopanas, Leimkühler e Drettakis
- O site do artigo, o código-fonte e os datasets estão disponíveis, permitindo tentar experimentos e reprodução diretamente
- O experimento em Unity se concentra na visualização em tempo real de arquivos de “modelo” Gaussian Splat já gerados
- A implementação está disponível em aras-p/UnityGaussianSplatting, e novos experimentos devem continuar depois
- Também é um ponto de interesse saber se é possível reduzir o tamanho dos dados, possivelmente aproveitando experimentos anteriores de compressão de floats
Do que é composto um Gaussian Splat
- Gaussian Splatting representa uma cena 3D como milhões de partículas, em vez de malhas poligonais, voxels ou campos de distância
- Cada partícula, isto é, uma “Gaussiana 3D”, contém as seguintes informações
- posição no espaço 3D
- rotação
- escala 3D não uniforme
- opacidade
- informações de cor
- A cor não é uma cor única, mas é representada por coeficientes de Spherical Harmonics de 3ª ordem, podendo variar conforme a direção do ponto de vista
- Na renderização, as partículas não são desenhadas como esferas 3D alongadas; elas são “splatadas” como uma Gaussiana 2D no espaço da tela
- O ponto central é transformar um conjunto de blobs com escala e cor em uma representação de cena baseada em fotos, e renderizá-lo rapidamente
Não é NeRF nem rasterização de função fixa
- Gaussian Splatting não é NeRF
- É explicitamente dito que não há elemento “Neural”
- O motivo de ser rápido também não é “porque usa o hardware de rasterização da GPU”
- A implementação oficial não usa o pipeline de rasterização
- Ela é implementada 100% em CUDA
- O desempenho da implementação oficial não vem da rasterização de função fixa, mas de uma renderização em software baseada em tiles que processa de forma eficiente milhões de partículas escalonadas
- Ainda assim, o rasterizador em “software sobre a GPU” baseado em tiles em si não é um conceito totalmente novo
Conexões com blocos técnicos antigos
- Gaussian Splatting em si se conecta a trabalhos como EWA Splatting, de por volta de 2001–2002
- Coloca blobs escalonados e orientados no espaço, calcula como eles são projetados na tela e então processa uma forma Gaussiana no espaço da tela
- O jogo de 1994 Ecstatica é um caso singular que usava um renderizador baseado em elipsoides
- Spherical Harmonics são usados há séculos na física e se tornaram amplamente conhecidos em computação gráfica por volta de 2000, por meio dos trabalhos de Ravi Ramamoorthi e Peter-Pike Sloan
- Ray tracing volume densities, de Kajiya & Von Herzen, de 1984, pode ser um dos primeiros usos em gráficos
- Um resumo relacionado pode ser visto na página do Patapom
- Point-Based Rendering também é uma área antiga
- Sistemas de partículas são usados há muito tempo em VFX e na representação de fenômenos não sólidos
- The Use of Points as a Display Primitive é um trabalho de 1985
- Surfels é um artigo de 2000
- A demoscene e ferramentas de VFX em tempo real também vêm usando abordagens de renderização não tradicionais
- Agenda Circling Forth, Ceasefire (all falls down..) e Number One / Another One, da Fairlight & CNCD, são exemplos
- Notch é uma ferramenta de VFX em tempo real com recursos para criar, simular e exibir objetos baseados em pontos e blobs
- fogleman/primitive é um exemplo de ferramenta de 2016 que representa imagens como conjuntos de primitive shapes
- “Dreams”, da Media Molecule, usava um renderizador baseado em splats, e a versão lançada parece combinar várias técnicas
- A apresentação “Learning from Failure”, de Alex Evans, pode ser vista na SIGGRAPH 2015 e na Umbra Ignite 2015
- A rasterização em tiles para partículas existe pelo menos desde Holy smoke! Faster Particle Rendering using Direct Compute, de Gareth Thomas, em 2014
- Dividir a tela em tiles e trabalhar dentro de cada tile pode reduzir o tráfego de memória
- Essa abordagem também se conecta ao modo de funcionamento geral das GPUs móveis; os primeiros projetos da PowerVR remontam a 1996, e o Pixel Planes 5, a 1989
Estado atual do UnityGaussianSplatting
- aras-p/UnityGaussianSplatting é uma implementação de visualizador para modelos Gaussian Splat
- O estado atual é próximo de “funciona, mas não é rápido”
- Ao renderizar a cena bicycle em 1200x800 em uma NVIDIA RTX 3080 Ti, a diferença de desempenho é grande
- Visualizador oficial: 7,40 ms, 135 FPS
- Implementação em Unity: 23,8 ms, 42 FPS
- Cerca de 4 vezes mais lenta
- O método de ordenação também afeta a diferença de desempenho
- A implementação em Unity usa um bitonic sort em GPU relativamente simples
- A implementação oficial usa um CUDA radix sort baseado no algoritmo OneSweep
- A abordagem de rasterização também é diferente
- A implementação oficial é um método baseado em tiles escrito em CUDA
- A implementação em Unity usa o pipeline comum de rasterização da GPU para renderizar cada splat como um quad no espaço da tela
- A implementação em Unity tem vantagens de portabilidade
- O código é escrito em HLSL comum dentro do Unity, então também funciona no Mac
- No Apple M1 Max, a mesma cena é renderizada em 108 ms, 9 FPS
- A memória de GPU usada atualmente pela implementação em Unity parece ser menor
- Visualizador oficial: 4,8 GB
- Implementação em Unity: 2,2 GB
- Número que inclui até a memória usada pelo Unity Editor
Tamanho dos dados e uso de memória
- Discussões sobre Gaussian Splatting tendem a se concentrar na qualidade e na velocidade de renderização, mas o tamanho dos dados e o uso de memória também são grandes problemas
- A cena bicycle ocupa 1,5 GB em disco
- Essa cena é composta por cerca de 6 milhões de blobs
- Cada blob usa cerca de 250 bytes
- Em tempo de execução, é necessária memória adicional para ordenação, renderização baseada em tiles etc.
- A apresentação de Dreams contém ideias que podem servir de referência para reduzir o tamanho
1 comentários
Opiniões no Hacker News
A formulação de que evitaram “neural” mesmo usando gradiente descendente e renderização diferenciável soa um pouco presunçosa
Conceitualmente, é parecido com NeRF: otimizar uma representação baseada em dados que aproxima variáveis relacionadas a uma cena 3D a partir de imagens. A diferença parece ser que o NeRF modela o campo de radiância, isto é, toda a função de transporte de luz, enquanto aqui eles parecem modelar apenas as condições de contorno onde a luz incide
Como o objeto é diferente, faz sentido usar uma base de representação mais simples, e os resultados parecem bons, mas é uma pena falar como se evitar redes neurais fosse, por si só, algo digno de elogio. Redes neurais não são usadas apenas por serem moda; elas são de fato aproximadores de funções poderosos, e a variedade de estruturas chamadas de “redes neurais” é muito ampla
Essa é só a impressão que tive pelo tom da introdução do post do blog, então pode ser diferente do artigo em si
Por isso, parece mais fácil de entender e também mais fácil de integrar a outros softwares 3D, como editores ou renderizadores, e parece que animação também seria possível. Um aproximador de funções de caixa-preta que representa a cena inteira de uma vez só não parece escalável nem elegante
Dito isso, mesmo quando redes neurais modelam bem um problema, muitas vezes não sabemos como o modelo treinado realmente funciona, e as exigências de dados e de retreinamento iterativo limitam sua utilidade para criar soluções de longo prazo
Aqui, prefiro interpretar que os autores fizeram uma piada amigável, não que tentaram alimentar uma pequena guerra cultural
Cada pixel renderizado é uma soma ponderada das contribuições de gaussianas dependentes do ponto de vista e sem limites definidos; portanto, a distinção de que o NeRF modela o campo de radiância enquanto isto modela apenas condições de contorno não está correta
Considerando ainda que o NeRF tem usado uma representação de harmônicos esféricos de baixo posto no domínio direcional, ele fica quase mais próximo de 3D+α, então surge a pergunta: por que escolher uma rede neural para reconstruir uma função de dimensionalidade tão baixa?
Na inferência, é preciso amostrar repetidamente a rede neural ao longo do raio de visão para cada pixel, mas representações comprimidas de campos de luz são um problema já tratado há muito tempo em computação gráfica, então essa parte soa bem estranha
Depois, Plenoxels removeu o “Ne” de NeRF e aumentou bastante o desempenho de treinamento e inferência, e o Instant NeRF da Nvidia compensou isso em certa medida ao interpolar embeddings de entrada sofisticados para uma pequena rede neural: https://nvlabs.github.io/instant-ngp/assets/mueller2022insta...
Na engenharia gráfica, redes neurais foram usadas amplamente sobretudo para reconstrução a partir de dados esparsos, especialmente remoção de ruído, o que é natural por ser um problema de alta dimensionalidade. Ainda assim, raramente superam algoritmos feitos à mão, e usar redes neurais pequenas para compressão parece ter futuro
Em computação gráfica há muita aproximação de funções, então existe espaço para redes neurais, mas as funções tratadas em geral são mais compreensíveis e controláveis, diferentemente de áreas como compreensão de linguagem natural, nas quais é quase impossível usar soluções algorítmicas manuais
Muitas conversas terminam em IA=ruim, CRYPTO=ruim. O problema não é que a opinião contrária esteja errada, mas que, se você decide a conclusão primeiro e para de pensar, não há como perceber se suas próprias ideias são completamente absurdas
Um trabalho realmente incrível
O texto menciona renderização baseada em pontos e sistemas de partículas, e nos jogos recentes há uma sensação de migração sutil para um novo estilo de partículas mais orientado a pontos do que a fragmentos de textura, mas que ainda se comporta como um sistema físico
Alguns exemplos são 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 e FF16
O ponto em comum é que parecem partículas pontuais transparentes e coloridas com física; especialmente em consoles, parecem ser usadas para obter efeitos baratos na GPU sem sobrecarregar a CPU. Fico curioso se alguém da área de desenvolvimento de jogos souber mais
Sem simulação de fluidos, um sistema de partículas baseado em pontos parece apenas fogos de artifício. A etapa seguinte foi cada partícula ter física própria, como momento ou vento, e ser renderizada como pequenos billboards de textura; isso foi usado para explosões e fumaça até relativamente pouco tempo atrás
Agora, com máquinas mais potentes e algoritmos físicos melhores, dá para rodar em tempo real simulações de fluidos em que as partículas interagem entre si, e os efeitos que vemos hoje parecem ir nessa direção
No mundo dos jogos 3D, há muitas vantagens conceituais e estruturais em lidar apenas com primitivas realmente 3D, e point sprites podem ser tratados quase como objetos 3D infinitamente pequenos
Por outro lado, quando se coloca sprites 2D em uma cena 3D, se houver transparência parcial é preciso ordená-los de trás para frente; eles não combinam bem com o z-buffer, entram em conflito com a ordem de batching otimizada para a GPU e tendem a penetrar superfícies 3D, revelando facilmente que são 2D
Para resolver esses problemas, foram se acumulando vários compromissos, como transparência screen-door, shaders que alteram a forma de gravação no z-buffer, alpha test, alpha-to-coverage etc.
Em VR, renderização baseada em imagens 2D dentro de cenas 3D se destaca de forma ainda pior do que em uma tela única, e o fato de serem billboards planos fica muito mais evidente. Somando esses motivos, há razões de sobra para querer fugir dos efeitos de sprites texturizados 2D em cenas 3D
Por causa da onda de IA, o fato de as GPUs estarem caminhando, com RT cores e tensor cores, para algo como “uma GPU de conjunto de instruções reduzido dentro da GPU” também parece ter alguma relação
Alguns anos atrás, a NVIDIA escreveu um kernel que movia kernels SE(3) para tensor cores, e não me surpreenderia se isso pudesse ser parcialmente portado para a parte de harmônicos esféricos do Gaussian splatting, tanto em compressão quanto em execução: https://developer.nvidia.com/blog/accelerating-se3-transform...
Como o Gaussian splatting sempre tem uma região de suporte no espaço 3D, deve ser bastante eficiente, e mesmo uma transformação aproximada e rápida pode produzir um resultado final bem bom
Também é relativamente fácil criar belos redemoinhos de pontos luminosos. Imagino que a Unreal Engine tenha algo parecido, mas não tenho muita experiência direta com ela
Não acho que tenha se originado ali, mas a primeira referência que consigo apontar é essa demo
Fiquei muito empolgado quando o artigo da Siggraph saiu pela primeira vez
Ao longo dos últimos 10 anos mais ou menos, fotografei de centenas de ângulos os quartos em que morei, pensando em algum dia recriá-los em 3D, e Gaussian splatting é a primeira técnica que parece capaz de reproduzi-los de um jeito quase real
Estou muito ansioso para, quando as ferramentas amadurecerem mais, poder revisitar esses quartos antigos e me deixar levar pela nostalgia
Não conheço bem a área, então talvez seja uma pergunta ignorante, mas esses vídeos parecem realmente incríveis
Pelo que entendo, a cena ou o campo de radiância é sempre estático e a iluminação fica pré-calculada; fico curioso se há possibilidade de evoluir para mudar a iluminação dinamicamente e até dar suporte a movimento
Em um campo de radiância não há conceitos como emissão, reflexão ou absorção da luz; tudo é condensado em um único valor de “luz transmitida”. Nesse sentido, um campo de radiância é mais próximo de uma foto 3D
Para mudar isso, seria preciso estimar a posição das fontes de luz, superfícies, materiais etc. por renderização inversa ou fotogrametria e então voltar a usar path tracing tradicional
Outra direção não seria animação, mas vídeo: capturar continuamente o campo de radiância ao longo do tempo e comprimir a semelhança entre quadros para obter consistência temporal
Também dá para juntar vários para criar uma animação: https://twitter.com/8Infinite8/status/1699460316529090568
Quanto a reiluminação, há muitas variantes de NeRF que dão suporte a isso, então também parece possível otimizar os parâmetros de material dos splats
Por exemplo, em uma cena interna, se uma mesa projeta uma sombra escura no chão, o NeRF ainda não entende fontes de luz e sombras; portanto, não consegue saber se o chão é preto, se é um piso branco coberto pela sombra da mesa, ou se há um Stanford bunny azul escondido dentro da sombra
Rigs de escaneamento 3D que capturam objetos pequenos, como rostos humanos, resolvem isso manipulando a iluminação e amostrando diretamente a BRDF. Se não for possível manipular a iluminação, talvez dê para estimar a BRDF, mas há limites
Adicionar animação depois pode ser fácil, mas para capturar a animação em si seriam necessárias várias câmeras, ou então depender de estimativas, como uma rede neural que, por se tratar de uma pessoa, imagina e preenche o outro lado
A Intel fez, há alguns anos, um projeto em que capturava uma cena com várias câmeras e permitia mudar a posição da câmera no pós-processamento; parece que miravam transmissões de futebol americano, mas não ouvi falar de um lançamento real. É preciso ter várias câmeras, ao estilo Matrix
Ou seja, seria um modo de fazer os dados serem animados conforme o horário do dia. A exigência de dados pode crescer, mas, com métodos de interpolação, talvez não seja tão ruim
Se uma cena estática tem 2 GB, acho que uma aproximação grosseira por horários do dia poderia ficar abaixo de 16 GB e ser renderizada em GPUs modernas. Depois disso, é questão de passar alguns anos otimizando enquanto esperamos o desempenho de nível H100 chegar ao consumidor
É sempre divertido quando a ciência supera as expectativas da ficção científica
Neste caso, pensei imediatamente no conceito de Braindance de Cyberpunk 2077: um recurso que permite circular pela memória visual de outra pessoa dentro do alcance em que ela percebeu a cena
Quando se move a câmera para um ponto diferente do ponto de vista original, o campo de visão colapsa como um aglomerado de pixels tridimensionais; é parecido com o conceito de blob daqui, mas, surpreendentemente, aparece de forma muito menos refinada do que neste artigo
https://steelseries.com/blog/how-to-braindance-cyberpunk-207...
Splatting em renderização volumétrica é uma técnica bastante antiga. Há o artigo de julho de 1991 de Westover, Lee Alan, “SPLATTING: A Parallel, Feed-Forward Volume Rendering Algorithm”
O segundo caso ninguém parece estar tentando esconder, e o primeiro não parece correto
Não sei de onde veio esse insight, mas na época eu morava perto de Boston e tinha filhos pequenos
Estou ansioso pela primeira implementação WebGPU nativa otimizada de renderização 3DGS
Também estou curioso sobre como comprimir e descomprimir os dados da cena de forma eficiente
Deixei algumas notas sobre essa questão em um thread no Zulip: https://xi.zulipchat.com/#narrow/stream/197075-gpu/topic/Gau...
Recentemente vi um vídeo que mostra como usar Gaussian splatting: Getting Started With 3D Gaussian Splats for Windows (Beginner Guide) - https://www.youtube.com/watch?v=UXtuigy_wYc
Curioso sobre o estado da arte em structure from motion
Quero saber como, na prática, hoje se transforma um vídeo de um espaço em uma cena 3D
É exatamente isso que entra como input no processo de reconstrução de cena descrito neste artigo
Pelo que sei, a abordagem básica de SfM não mudou muito nos últimos 10 anos ou mais, e se resume a extração de características de imagem como SIFT, matching heurístico, bundle adjustment e remoção de outliers
A resposta é a fotogrametria comum, e o interesse e a praticidade de abordagens no estilo NeRF também vêm crescendo aos poucos
Ainda assim, é surpreendente que relações espaciais adicionais que podem ser inferidas só pelo fato de ser vídeo não recebam mais atenção. Parece que a restrição de que a câmera só pode se mover de certas maneiras entre frames poderia ser usada na estimativa da pose da câmera
Existe a ideia de rodar marching cubes sobre as Gaussian splats para extrair uma malha, mas acho que ainda não vi um caso real disso
No fim dos anos 90, renderizei isosuperfícies de voxels com blobs
Eu escaneava os voxels de superfície em todo o array 3D de voxels, calculava as normais pelo gradiente de densidade local e depois quantizava em uma de 240 opções
Em seguida, usava uma tabela de vetores de deslocamento para criar cadeias de voxels de superfície, e a maioria dos voxels ocupava 2 bytes: um índice de deslocamento em relação ao voxel anterior e um índice de vetor normal
A iluminação para os 240 vetores normais era pré-calculada e colocada em uma tabela de consulta, e o software conseguia pintar pequenos círculos coloridos no z-buffer muito rapidamente
A grande frustração na época era não poder usar perspectiva. Como os vetores de deslocamento eram transformados para o espaço de tela a cada frame, o processo era pintar o blob, aplicar o offset, consultar a cor e pintar de novo. Havia um valor de deslocamento que marcava o fim da cadeia e o próximo armazenamento de posição absoluta, mas a maioria dos voxels tinha 2 bytes