← Blog
技術メモ3DGSワークフロー

3DGSをブラウザで動かすまで:撮影から軽量化・埋め込みの実践メモ

2026-07-29

3DGS(3D Gaussian Splatting)の魅力は、実際の空間を撮って、そのままブラウザで“ぐるっと”動かせることです。ただ、撮ってから実際にWebで軽快に動くまでには、いくつか実践的なコツとハマりどころがあります。このサイトの作例(Works)を作る中で得た知見を、ワークフローの順にまとめました。

全体の流れ

  1. 撮る(360°カメラで現地撮影)
  2. 3DGS化(撮影データ → スプラット)
  3. 軽量化(Webで動くサイズへ)
  4. 配信(外部ホスティング)
  5. 埋め込み(サイトに表示)

順番に、要点と“ハマりどころ”を見ていきます。

1. 撮る

DJI Osmo 360 のような360°カメラで、対象の空間を歩きながら撮影します。きれいなスプラットを作るコツは:

  • 明るさを一定に —— 露出が急に変わるとつなぎ目が破綻しやすい
  • 動く人・物を減らす —— 動体はノイズや“ゴースト”の原因になる
  • 視差を稼ぐ —— 同じ場所で回すだけでなく、少しずつ位置をずらして回り込む
  • 鏡・ガラス・水面は苦手 —— 反射や透明はうまく再構成できないことを意識する

小規模な室内なら、数分〜十数分の撮影で十分なデータが取れます。

2. 3DGS化

撮影データから 3D Gaussian Splatting を再構成します。ツールはいくつかありますが、ここでは LichtFeld Studio を使う前提で進めます。出力は .spz(SPZ形式)です。

3. ハマりどころ①:「Unsupported SPZ version: 4」

ここが最初の関門でした。LichtFeld Studio が書き出す .spzSPZ v4 ですが、Web表示に使う定番ビューア(Three.js 系の Spark など)は v1〜v3 までしか読めません。そのまま貼ると、こうなります:

Unsupported SPZ version: 4

解決策は、圧縮PLY(.compressed.ply)に変換すること。PlayCanvas の splat-transform が手軽です:

npx @playcanvas/splat-transform input.spz -H 0 output.compressed.ply

-H 0 は球面調和(view-dependent color)の次数を 0 にする指定です。見た目への影響を抑えつつ、ファイルサイズを大きく減らせます。

4. ハマりどころ②:軽量化(点の間引き)

スマホでの表示速度は 3DGS の“生命線”です。数千万スプラットのままだと、モバイルでは重くて実用になりません。目安は 30〜40MB 程度。大きい場合は点数を間引きます。

splat-transform の間引き(-d)は「最終アクションかつ出力が .ply」という制約があるので、2段階に分けます:

# 1) 間引いて中間PLYに
npx @playcanvas/splat-transform input.spz -H 0 -d 2200000 mid.ply

# 2) 圧縮PLYに変換
npx @playcanvas/splat-transform mid.ply output.compressed.ply

-d 2200000 は「残す点数の上限」です。対象に応じて調整します(作例では GB250 が約30MB、愛宕山ケーブルカーが約34MB に収まりました)。

5. ハマりどころ③:どこに置くか(配信とCORS)

3DGSファイル(数十MB)は、サイトのリポジトリには入れません。外部ホスティングに置いて公開URLを読み込むのが基本です。ここにも罠があります:

  • raw.githubusercontent.com は CORS ヘッダを返すので、ブラウザから直接読めます(公開リポジトリが必要)
  • jsDelivr は 20MB を超えると 403 —— 大きい3DGSには使えません
  • Private リポジトリの Releases は匿名ダウンロード不可 —— ビューアから読めません
  • GitHub の Web アップロードは 25MB 上限 —— 大きいファイルは git コマンドでコミットする

まとめると「公開リポジトリ + raw URL」がクレカ不要で確実です。もちろん、Backblaze B2 や Cloudflare R2 のような CORS 設定可能なオブジェクトストレージでも構いません。

6. 埋め込み:ブラウザで動かす

あとは Three.js + Spark(@sparkjsdev/spark)などで .compressed.ply を読み込み、ドラッグ回転・ホイールズームを付ければ完成です。読み込み後にモデルの重心と大きさを自動計算してカメラを自動フィットさせると、スキャンごとに座標やスケールが違っても、必ず画面に収まります。

スマホ配慮としては:

  • ファイルは軽く(前述の 30〜40MB を目安に)
  • devicePixelRatio は上限 2 程度にクランプして描画負荷を抑える
  • 数十MBのダウンロードは時間がかかるので、読み込み中のプレースホルダを必ず出す

まとめ

3DGS は「撮って終わり」ではなく、Webで軽快に動かすまでが本番です。要点はこの3つ:

  • LichtFeld Studio の SPZ v4 は圧縮PLYへ変換(Unsupported SPZ version: 4 対策)
  • 30〜40MB を目安に間引き(-d は2段階で)
  • 公開リポジトリ + raw URL(または CORS 可のストレージ)で配信

同じような空間スキャンを試してみたい方は、お問い合わせからお気軽にどうぞ。実際に指で動かせる作例は Works で触れます。