はじめに
この記事は STYLY Advent Calendar 2025 の記事です。
前回の記事「コード0行でGaussian Splatting配信システムを作った —— AI駆動開発2日間の記録」では、AI駆動開発で「GS Bridge」を土日2日間で開発した経緯をお伝えしました。本記事では、GS Bridgeの技術的な詳細を解説します。
📝 Note: この記事自体もAI(Claude)を活用して執筆しています。
GS Bridgeとは
GS Bridgeは、3D Gaussian Splatting(3DGS)データをWebブラウザで編集し、HMDにリアルタイム配信してマルチユーザーで閲覧できるシステムです。
主な機能
| 機能 | 説明 |
|---|---|
| PLYアップロード | Scaniverseなどで撮影した3DGSデータをドラッグ&ドロップで読み込み |
| 3Dプレビュー | Webブラウザ上でGaussian Splattingをリアルタイム表示 |
| 編集機能 | 選択範囲の削除、自動背景除去 |
| HMD配信 | ボタン一つでPICO4/Quest3などに送信 |
| マルチユーザー | 複数人が同時に同じデータを閲覧 |
想定ユースケース:製造業での3Dレビュー
- 工場設備の点検: 設備をScaniverseでスキャン → 不要部分を編集で除去 → 複数人でHMDレビュー
- 製品デザインレビュー: 試作品の3Dスキャンを関係者全員で同時確認
- 遠隔地との共同作業: 本社と工場で同じ3Dデータをリアルタイム共有
システムアーキテクチャ
GS Bridgeは、Web(編集・配信) → Firebase(中継) → Unity/HMD(受信・表示) の3層構成です。
┌─────────────────────────────────────────────────────────────────┐
│ GS Bridge Architecture │
└─────────────────────────────────────────────────────────────────┘
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Web App │ │ Firebase │ │ Unity/HMD │
│ (編集側) │ │ (中継) │ │ (表示側) │
└──────────────┘ └──────────────┘ └──────────────┘
│ │ │
│ ① PLYアップロード │ │
│ ──────────────────────>│ │
│ │ Storage に保存 │
│ │ │
│ ② セッション更新 │ │
│ ──────────────────────>│ │
│ │ Firestore に記録 │
│ │ │
│ │ ③ ポーリング │
│ │<───────────────────── │
│ │ │
│ │ ④ PLYダウンロード │
│ │ ─────────────────────> │
│ │ │
│ │ ┌─────────────────────┐
│ │ │ STYLY NetSync │
│ │ │ (マルチユーザー同期) │
│ │ └─────────────────────┘
│ │ │
│ │ ┌──────┴──────┐
│ │ │ │
│ │ ┌──┴──┐ ┌──┴──┐
│ │ │HMD 1│ │HMD 2│
│ │ └─────┘ └─────┘
データフロー
- WebアプリでPLYファイルを編集
- 「HMDに送信」ボタンでFirebase Storageにアップロード
- Firestoreのセッション情報(URL、ハッシュ)を更新
- Unity側がFirestoreをポーリングし、変更を検知
- 新しいPLYをダウンロード&パース&表示
- STYLY NetSyncが複数HMD間の同期を担当
Webアプリの実装
技術スタック
| 技術 | 用途 |
|---|---|
| Next.js 14 | フレームワーク(Static Export) |
| React 18 | UI構築 |
| TypeScript | 型安全性 |
| @mkkellogg/gaussian-splats-3d | 3DGSレンダリング |
| Three.js | 3D描画基盤 |
| Firebase | 認証・ストレージ・データベース |
| Tailwind CSS | スタイリング |
主要コンポーネント構成
src/
├── app/
│ └── page.tsx # メインページ(状態管理の中心)
├── components/
│ ├── SplatViewer.tsx # 3DGSビューア(Three.js + gaussian-splats-3d)
│ ├── EditPanel.tsx # 編集パネル(選択・削除・背景除去)
│ ├── FileUploader.tsx # ファイルアップロード
│ ├── HMDPanel.tsx # HMD送信パネル
│ └── LookPanel.tsx # 表示設定(背景色など)
├── lib/
│ ├── splat-loader.ts # PLYパーサー
│ ├── gaussian-editor.ts # 編集処理(選択・削除・エクスポート)
│ └── firebase/ # Firebase連携
└── types/
└── index.ts # 型定義
3DGSビューア(SplatViewer)
Webブラウザ上でGaussian Splattingを表示するために、@mkkellogg/gaussian-splats-3dライブラリを使用しています。
主な機能:
- PLYファイルのリアルタイムレンダリング
- マウス操作によるカメラコントロール(OrbitControls)
- 選択範囲のボックス/スフィア表示
- 選択ハンドルのドラッグ操作
編集機能(EditPanel)
ボックス選択による削除
3D空間上にボックスを配置し、その範囲内(または範囲外)のGaussianを削除できます。ボックスの各面にハンドルがあり、ドラッグでサイズ調整が可能です。
自動背景除去
Gaussian Splattingデータには、撮影時に写り込んだ背景(床、壁、天井など)が含まれることがあります。自動背景除去機能では、以下のアルゴリズムで不要部分を検出・削除します:
- 低不透明度の除去: 透明度の低いGaussianを閾値でフィルタリング
- 上部の除去: Y座標が一定以上のGaussian(天井など)を除去
- 周辺の除去: 中心から離れたGaussian(背景の壁など)を除去
HMD送信(HMDPanel)
「HMDに送信」ボタンを押すと、以下の処理が実行されます:
- 編集済みデータをPLY形式にエクスポート
- Firebase Storageにアップロード
- FirestoreのセッションドキュメントにURL・ハッシュを記録
ハッシュ値を使うことで、Unity側は「データが更新されたかどうか」を効率的に判定できます。
Unity/HMD側の実装
技術スタック
| 技術 | 用途 |
|---|---|
| Unity 6 | ゲームエンジン |
| C# | スクリプト |
| カスタムシェーダー(HLSL) | 3DGSレンダリング |
| UnityWebRequest | HTTP通信 |
| STYLY NetSync for LBE | マルチユーザー同期 |
主要コンポーネント
Assets/00_3DGS_Transporter/
├── Scripts/
│ ├── Core/
│ │ ├── GaussianSplatData.cs # データ構造
│ │ └── PLYParser.cs # PLYパーサー
│ ├── Network/
│ │ └── GS_ModelManager.cs # Firestore監視&ダウンロード
│ └── Rendering/
│ └── GaussianSplatRenderer.cs # GPUレンダリング
└── Shaders/
└── GaussianSplat.shader # カスタムシェーダー
Firestoreポーリング(GS_ModelManager)
Unity側は一定間隔(デフォルト2秒)でFirestoreのセッションドキュメントをポーリングします。
[ポーリングの流れ]
1. Firestore REST APIにGETリクエスト
2. レスポンスからcurrentSplatUrl, currentSplatHashを取得
3. ハッシュが前回と異なれば → 新しいPLYをダウンロード
4. 同じなら → 何もしない(効率化)
Firestore REST APIを直接使用することで、Firebase SDKへの依存を避け、軽量な実装を実現しています。
PLYパーサー
ダウンロードしたPLYファイル(バイナリ形式)をパースし、以下のデータを抽出します:
- 位置 (x, y, z)
- 色 (Spherical Harmonics係数 → RGB変換)
- 不透明度 (sigmoid適用)
- スケール (exp適用)
- 回転 (クォータニオン)
GPUレンダリング(GaussianSplatRenderer)
Gaussian Splattingのレンダリングは、カスタムシェーダーを使用してGPU上で行います。
主な処理:
- ソート: カメラからの距離でGaussianをソート(透明度の正しい合成のため)
- 共分散行列の計算: 各Gaussianの3D楕円体を2Dに投影
- ビルボード描画: 計算された楕円をカメラに向けて描画
- アルファブレンディング: 透明度に基づいて色を合成
STYLY NetSync for LBEの活用
GS Bridgeのマルチユーザー機能は、STYLY NetSync for LBEを活用しています。
STYLY NetSyncとは
STYLY NetSyncは、複数のHMDデバイス間でオブジェクトの位置・状態を同期するための仕組みです。LBE(Location-Based Entertainment)向けに最適化されており、同一空間で複数人が同じXR体験を共有できます。
詳細は公式記事をご参照ください:
👉 STYLY NetSync for LBE でマルチユーザー体験を作る
GS Bridgeでの活用ポイント
| 機能 | GS Bridgeでの使い方 |
|---|---|
| 位置同期 | 各ユーザーのアバター位置を共有 |
| オブジェクト同期 | 3DGSモデルの表示状態を全員で共有 |
| ルーム管理 | 同じルームIDのユーザーが同じデータを閲覧 |
導入の容易さ
前回の記事でも触れましたが、STYLY NetSyncの環境構築は約30分で完了しました。公式記事の手順に従うだけで、マルチユーザー同期という複雑な機能を簡単に導入できます。
対応デバイス
GS BridgeはPICO4/PICO4 Ultraで開発しましたが、STYLY NetSyncはQuest3などにも対応しています。プラットフォームを跨いだマルチユーザー体験も可能です。
製造業ユースケース例
ユースケース1:工場設備の遠隔レビュー
[シナリオ]
本社の設計チームと工場の保全チームが、設備の改修計画を議論したい。
[GS Bridgeの活用]
1. 工場でScaniverseを使って設備を3Dスキャン
2. Webアプリで不要部分(周囲の機材など)を除去
3. HMDに送信
4. 本社・工場の担当者がそれぞれHMDを装着
5. 同じ3Dモデルを見ながらリアルタイムで議論
ユースケース2:製品デザインの複数人レビュー
[シナリオ]
試作品のデザインを、デザイナー・エンジニア・マーケティングの3者でレビュー。
[GS Bridgeの活用]
1. 試作品をScaniverseでスキャン
2. Webで背景を除去し、製品のみを抽出
3. 3人がHMDを装着し、同時に同じモデルを確認
4. 「この角度から見ると〜」など、空間的な議論が可能
ユースケース3:作業手順の3D記録・共有
[シナリオ]
熟練作業者の技術を3Dで記録し、新人教育に活用。
[GS Bridgeの活用]
1. 作業現場をGaussian Splattingで記録
2. 重要なポイントだけを切り出して編集
3. 教育担当者と新人が同時にHMDで確認
4. 「ここに手を入れて〜」など、立体的な説明が可能
まとめ
GS Bridgeは、以下の技術を組み合わせて実現しています:
| レイヤー | 技術 | 役割 |
|---|---|---|
| Web | Next.js + gaussian-splats-3d | 編集・プレビュー |
| 中継 | Firebase (Storage + Firestore) | データ保存・状態管理 |
| HMD | Unity + カスタムシェーダー | 高品質レンダリング |
| 同期 | STYLY NetSync for LBE | マルチユーザー |
STYLY NetSyncを活用することで、マルチユーザー同期という複雑な機能を短時間で導入できました。Gaussian Splattingという新しい3D表現技術と組み合わせることで、製造業での3Dレビューなど、実用的なユースケースに対応できるシステムが構築できます。
興味のある方は、ぜひSTYLY NetSyncを試してみてください。






