Pompežev kot

Ker stvari občasno zapišem

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.

Izotropne Gaussovke. Vidimo, da je upodobitev znatno manj točna kot z uporabo anizotropnimi Gaussovk na sliki 3 .

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

Primerjava med ortografsko (izometrično) projekcijo in linearnim približkom z Jakobianom iz [2].

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.

Primerjava treh velikosti Gaussovk (od prevelikih do premajhnih). Primerjamo lahko tudi z sliko 1, kjer je upodobitev sestavljena iz izotropnih Gaussovk. Vidimo, da anizotropija Gaussovk močno prispeva k kvaliteti upodobitve.
Vidimo, kako je tekst na čevlju z uporabo anizotropnih Gaussovk jasno berljiv.
Mešano na žaru. (Prvo) Plišasta igrača. (Drugo) Vlak. (Tretje) Izgled vlaka, ko namesto Gaussovk uporabimo kar ostre zapolnjene elipse \(\mathbf{r}^T M \mathbf{r} < R\) za nek \(R > 0\). Tako se še lepše vidi oblika in anizotropija Gaussovk.

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
Čas upodabljanja v sličicah na sekundo. Izmerjeno brez sinhronizacije z osvežitveno frekvenco zaslona naprave. Navedbe \(>240\) FPS označujejo, da je tak način klicanja, t. j. z uporabo 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
Čas sortiranja z implementacijo radix sort algoritma v C. Vidimo, da je za manjši dataset 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
Čas sortiranja v JS s podobno implementacijo radix sort algoritma.

Viri

[1]
B. Kerbl, G. Kopanas, T. Leimkühler, in G. Drettakis, „3d gaussian splatting for real-time radiance field rendering.“, ACM Trans. Graph., let. 42, št. 4, str. 139–1, 2023.
[2]
M. Zwicker, H. Pfister, J. Van Baar, in M. Gross, „EWA volume splatting“, v Proceedings Visualization, 2001. VIS’01., IEEE, 2001, str. 29–538.