Gaussian splatting
WebGl demo progamček za tehniko upodabljanja oblakov točk z množico tri-dimenzionalnih Gaussovk
Uvod
Oblak točk je diskretna množica točk v 3D prostoru, kjer vsaki od točk pripišemo barvo in velikost. Točke so tipično zajete z 3D skeniranjem fizičnih objektov in površin. Uporabljajo se npr. v arhitekturi, arheologiji in na splošno povsod, kjer potrebujemo zajeti tri-dimenzionalen pogled na objekt oz. prostor.
Gaussian splatting je sodobna metoda za upodabljanje oblakov točk, ki temelji na razpršenih Gaussovih jedrih. Metodo je populariziral Kerbl et al. [1], kjer so prikazali, da omogoča učinkovito in kakovostno vizualizacijo kompleksnih prizorov. Ključna ideja je upodabljanje oblaka točk, kjer vsaka točka nosi parametre Gaussove funkcije v prostoru.

Implementacija metode je preprostejša za izotropne Gaussovke (glej sliko 1), saj so te invariantne na rotacije, ko pogled premikamo okoli prizora. A tudi neizotropne Gaussovke so zaprte pod linearnimi preslikavami, kar pomeni, da lahko diagonalno kovariantno matriko \[\Sigma = \begin{pmatrix} \sigma_1^2 & 0 & 0 \\ 0 & \sigma_2^2 & 0 \\ 0 & 0 & \sigma_3^2 \end{pmatrix},\] transformiramo z rotacijskim zgornje-levim \(3\times 3\) delom view matrike \(V\), ki predstavlja inverz premika kamere \[\Sigma' = V_{3\times 3} \Sigma V_{3\times 3}^T,\] nato pa izrazimo zgornje-desno podmatriko \[M = (\Sigma'_{2\times 2})^{-1} = \begin{pmatrix} M_{11} & M_{12} \\ M_{12} & M_{22} \end{pmatrix},\] ki zdaj opisuje kvadratično formo \(\mathbf{r}^T M \mathbf{r}\) v ravnini \((X, Y)\), pravokotni na žarek kamere. Marginalna porazdelitev Gaussovke \(\Sigma\), če bi jo pointegrirali po vzporednih žarkih iz kamere, je preproste oblike \[f(X, Y) = e^{-\mathbf{r}^T M \mathbf{r}} = e^{-M_{11} X^2 - 2M_{12} XY - M_{22} Y^2}.\] Tako porazdelitev v ravnini \((X, Y)\), pravokotni na vzporedne žarke kamere, lahko preprosto upodobimo z trivialnim računom v fragment shader-ju, po tem, ko matriko \(M\) pripravimo v vertex shader-ju. Na kvadrate, ki so stalno orientirani proti kameri (ang. billboards), rendiramo marginalno 2-dimenzionalno porazdelitev \(f(X, Y)\).
Perspektivna preslikava


Ker Gaussove funkcije v 3D prostoru projiciramo v 2D ravnino zaslona, moramo upoštevati perspektivno preslikavo. Ta preslikava ni linearna in Gaussovke, preslikane z perspektivno preslikavo, niso 2-dimenzionalne Gaussovke. Da račun vseeno ostane preprost, prespektivo približno upoštevamo z linearno aproksimacijo prvega reda, torej Jacobijevo matriko. Sam sem jo vzel kar iz enačbe (25) v članku [2]. Izgled tega približka na preprostem primeru vidimo na sliki 2.
Rezultati
Na sliki 3 primerjamo tri velikosti Gaussovk. Na sliki 4 vidimo, kako je tekst na čevlju jasno berljiv. Na sliki 5 prikazujemo različne upodobitve, vključno s plišasto igračo, vlakom in varianto, kjer namesto Gaussovk uporabimo ostre zapolnjene elipse.







Hitrost
V tabeli 1 prikazujemo hitrost rendiranja (v sličicah na sekundo) dveh različnih datasetov na dveh različnih napravah.
nike.splat |
train.splat |
|
---|---|---|
RTX 3060 | \(>240\) FPS | \(>240\) FPS |
Pixel 71 | \(>240\) FPS | \(\sim\)40 FPS |
i5-8350U integriran GPU | \(\sim200\) FPS | \(\sim\)40 FPS |
setTimeout(render, 0)
, omejil FPS na to verednost. Ko sem
setTimeout
zamenjal z
requestAnimationFrame(render)
, je v teh primerih bilo doseženih stabilnih
\(60\)
FPS oz.
\(90\)
FPS (za OnePlus telefon z
\(90\,\mathrm{Hz}\)
zaslonom). Na i5-8350U integrirani GPU so bile meritve nekoliko omejene, saj so se pri tako hitrem
rendiranju začele pojavljati resne probleme z
crash-anjem grafičnih gonilnikov. Vseeno sem z uporabo sinhroniziranega
requestAnimationFrame
dosegel 30 FPS oz. 20 FPS za
nike.splat
oz.
train.splat
.
Hitrost sortiranja
Da bi pospešil WebGL implementacijo, sem implementiral radix sort v C, ki sem ga želel uporabiti v WebAssembly
(WASM) na web worker-ju. Meritve za tako C implementacijo so prikazane v tabeli 2. Vendar pa zastavica -s STANDALONE_WASM
v orodju emcc
ne podpira
shared spomina, kar mi je onemogočilo uporabe na web worker-ju. Zaradi pomanjkanja časa sem
implementacijo prepisal v JavaScript, kjer trenutno radix sort teče na spletnem delavcu. Meritve za to
počasnejšo implementacijo vidimo na sliki 3
Naprava | nike.splat | train.splat |
---|---|---|
i5-12400F | \(\sim\)7 ms | \(\sim\)28 ms |
i5-8350U | \(\sim\)14 ms | \(\sim\)54 ms |
nike.splat
sortiranje zadostno hitro za prikaz v realnem času.
Meritve hitrosti trenutne JS implementacije sortiranja so prikazane v tabeli 3.
Naprava | nike.splat | train.splat |
---|---|---|
i5-12400F | \(\sim\)48 ms | \(\sim\)170 ms |
Pixel 7a | \(\sim\)100 ms | \(\sim\)400 ms |
i5-8350U | \(\sim\)140 ms | \(\sim\)500 ms |