本文へスキップ

3D Gaussian Splatting for Browser

2024.12
three.jsのシーンと3DGS Viewerを統合して、glbとsplatを同時に描画する

Three.js + 3DGS

threejsのシーンと3DGS Viewerを統合することで、glbとsplatを同時に描画できる。
レンダラー、カメラなどはthree.jsを使用するので、基本的にはglbのアニメやカメラワークなども通常のthree.jsのシーンと同じ。
3DGSのライブラリは下記を使用。npmもある。OSSなので、ディレクトリごとローカルに保存すれば、カスタムもできる。
https://github.com/mkkellogg/GaussianSplats3D

問題

splatと3d rendererの回転が合わない。GaussianSplats3D.Viewer()にthreejsのカメラを渡すとこうなる。
splatの読み込み時に回転角を手動で直しています。

Screenshot 2024-12-19 at 14.56.33.png

3DGSのファイルフォーマット

(3DGSオリジナルはply)。ウェブでは.splatか.ksplat?
その他 → Compressed PLY, SPZ

ksplat

https://projects.markkellogg.org/threejs/demo_gaussian_splats_3d.php
このページの下にConvert a .ply or .splat to .ksplatがある。またはローカルでKSplatLoaderで変換できる。

SPZ

https://github.com/nianticlabs/spz
scaniverse(niantic)が3DGSのファイル形式として.spzをオープンソース化。plyに比べ90%圧縮。
8thwall Niantic StudioはSPZだけをサポート。https://www.8thwall.com/docs/ja/studio/guides/gaussian-splats/
Babylon向けのspz loader packageは開発がある。threejsはなさそう。https://zenn.dev/drumath2237/articles/release-spz-loader

3DGS Viewer

  • pmdrsの出しているdrei splatコンポーネント。vanilla版もある。(.splat のみ対応)

https://github.com/antimatter15/splat をコンポーネント化したもの。
https://drei.docs.pmnd.rs/abstractions/splat

コード事例

ライブラリなしの最小限。threejs sceneとGSの重なり順もちゃんとしてそう。
jolly-water-immus4

GS編集エディター

  • SuperSplat
    Screenshot 2024-12-19 at 16.40.20.png

OSS

https://playcanvas.com/supersplat/editor
ローカルで動かすなら
https://github.com/playcanvas/supersplat

git clone git@github.com:playcanvas/super-splat.git
git submodule update --init --recursive
npm install
npm run build
npm run serve

.ply to .splat converter
https://github.com/antimatter15/splat/blob/main/convert.py


未検証

複数のsplatを同時にシーンに追加できないかも? 重なりがおかしくなる?

これは浮いているシューズも.splat。

Threlte – Rapidly build interactive 3D apps for the web

Threlte の Gaussian Splatting サンプル

Tips

SortWorker.jsにてuseSharedMemoryを使うらしい。astroでは下記の設定が必要。

https://stackoverflow.com/questions/72881660/web-worker-blocked-by-self-crossoriginisolated-on-cypress

// astro config
export default defineConfig({
  server: {
    headers: {
      "Cross-Origin-Opener-Policy": "same-origin",
      "Cross-Origin-Embedder-Policy": "require-corp"
    }
  }
});