[WEB Add] WIRED ROOM - 3Dウォークスルー型パーソナル展示空間
WIRED ROOM とは
WIRED ROOM は、自分だけの3D空間を作って公開できる Web アプリケーションです。
ブラウザ上で3D空間を歩き回り、画像・動画・VRMフィギュア・クレジットボードを自由に配置して、自分だけの展示空間を作れます。作った部屋は ZIP でエクスポートして、好きなサーバーに置くだけで公開できます。Meta Quest の VR にも対応しています。
部屋同士はポータルで繋がります。中央サーバーはありません。各自が自分のサーバーに自分の部屋を持ち、ポータルを通じて互いの空間を行き来できます。
特徴
サーバー不要 — 静的ファイルだけで動きます。Node.js も PHP もデータベースも不要。Netlify、GitHub Pages、Vercel、Cloudflare Pages など、無料の静的ホスティングで公開できます。
ビルド不要 — npm install もビルドコマンドも不要。importmap + CDN で Three.js を読み込むので、ファイルをサーバーに置くだけで動きます。
VR 対応 — Meta Quest 2 / 3 のブラウザから VR モードで入室できます。コントローラーで移動、ポータルを通じて別サーバーの部屋へ VR のまま移動できます。
ポータル接続 — 部屋同士がポータルで繋がります。自分の部屋から友達の部屋へ、友達の部屋からさらに別の部屋へ。サーバーが違っても関係ありません。
データ駆動 — 部屋の設定は JSON で定義されます。配置情報もすべて JSON。手動で編集することもできます。
荒らし対策 — 中央サーバーがないので、荒らす場所がありません。各自が自分のファイルを管理します。
Live Demos
5つの異なるホスティングサービスにデプロイされた、同じ静的ファイルによるデモです。サーバー間をポータルで移動できます。
| ホスト | URL |
|---|---|
| Netlify | https://lain-lab.com/room/ |
| GitHub Pages | https://fixtan.github.io/WIRED_ROOM/ |
| Vercel | https://room-vercel.vercel.app/ |
| Cloudflare Pages | https://room-cloudflare.fixjp.workers.dev/ |
| Render | https://room-render.onrender.com/aisle/ |
すべての部屋がポータルで接続されています。VR でサーバー間を歩いて移動できます。
はじめかた
1. リポジトリをクローン
git clone https://github.com/fixtan/WIRED_ROOM.git
cd WIRED_ROOM
2. 部屋モデルをダウンロード
部屋の GLB ファイルは Sketchfab から入手します(すべて無料ライセンス)。
assets/room/models.json にダウンロード先 URL の一覧があります。
各モデルの GLB をダウンロードして assets/room/ に配置してください:
assets/room/
├── room_blank.glb
├── living_room_interior_free.glb
├── living_roomkitchenbedroom.glb
├── comfy_living_interior_-_cgt_345_final.glb
└── loft_interior_6_for_free.glb
3. デプロイ
フォルダ全体を静的ファイルサーバーにアップロードし、index.html を開きます。
ビルド不要。npm install 不要。ファイルをサーバーに置くだけです。
ローカルで試す場合は、VS Code の Live Server 拡張機能や npx serve などの簡易サーバーが使えます。
初回セットアップウィザード
初めて起動すると、4ステップのセットアップウィザードが表示されます。
STEP 1 — 部屋を選ぶ
models.json に登録されたテンプレートから部屋を選びます。サムネイル・作者名・ポリゴン数が表示されるので、好みと環境に合わせて選択してください。カスタム GLB をアップロードすることもできます。
STEP 2 — アバターを選ぶ 同梱の VRM(男性・女性)から選ぶか、自分の VRM ファイルをアップロードします。アップロードした VRM は IndexedDB に保存され、次回以降も使えます。
STEP 3 — スカイを選ぶ 4種類のプロシージャルスカイボックスから選択します。
| プリセット | 雰囲気 |
|---|---|
| Night | 星空 + 月。暗めの落ち着いた雰囲気 |
| Sunset | 夕焼け + 雲。暖色系 |
| Day | 青空 + 白い雲。明るい |
| WIRED | 黒背景 + 緑グリッド。サイバー感 |
STEP 4 — 部屋名を入力 部屋の名前を自由に設定します。
設定は localStorage に保存されます。次回以降はウィザードをスキップして直接入室します。
操作方法
PC(デスクトップブラウザ)
| 入力 | 動作 |
|---|---|
| W / A / S / D | 移動(前後左右) |
| ↑ / ↓ / ← / → | 移動(矢印キーでも可) |
| マウス移動 | 視点操作(カメラ回転) |
| ダブルクリック | 配置済みメディアを選択して再編集 |
| 右クリック | コンテキストメニュー表示(ポインター解放時) |
| Tab | コンテキストメニュー表示(ポインターロック中) |
| E | ポータル操作(近くにポータルがある時) |
| / (スラッシュ) | 公開モードと編集モードの切り替え |
VR(Meta Quest)
| 入力 | 動作 |
|---|---|
| 左スティック | 移動(ヘッドセットの向き基準) |
| 右スティック | 旋回 |
| A ボタン | ポータル操作 |
| Y ボタン | メニュー表示/非表示 |
コンテキストメニュー(編集モード)
右クリックまたは Tab キーでコンテキストメニューが開きます。ここから部屋のカスタマイズを行います。
部屋設定
| メニュー | 説明 |
|---|---|
| Room Info | 部屋のタイトル、クレジット、お知らせテキストを編集 |
| Reset Settings | localStorage をクリアしてウィザードを再表示 |
| Fullscreen | フルスクリーン切り替え |
| Take Thumbnail | 部屋のスクリーンショットを撮影(IndexedDB に保存) |
エクスポート / インポート
| メニュー | 説明 |
|---|---|
| Export ZIP | 公開用 ZIP をダウンロード。サーバーに置くだけで公開可能 |
| Import ZIP | 以前エクスポートした ZIP から部屋を復元 |
| Clear All Data | すべてのデータ(IndexedDB + localStorage)を削除して初期化 |
部屋カスタマイズ
| メニュー | 説明 |
|---|---|
| Add Custom Room | 自分の GLB 部屋モデルをアップロード |
| Adjust Room | スケール・位置・回転のスライダーでリアルタイム調整 |
メディア配置
| メニュー | 説明 |
|---|---|
| Add Image | 画像をアップロードして空間内に配置 |
| Add Video | MP4 動画をアップロードして配置 |
| Credit Board | クレジットボードやお知らせメッセージを表示 |
| Add My Avatar | VRM をフィギュアとして配置(ポーズ付き) |
配置したオブジェクトはダブルクリックで再選択し、位置・回転・スケールを再編集できます。
ポータル管理
| メニュー | 説明 |
|---|---|
| Add Portal | グローバルポータル(緑)を作成 |
| Add Friend Portal | フレンドポータル(青)を作成 |
| Edit Friend List | フレンドポータルの接続先を管理 |
| Add Works Portal | ワークスポータル(黄)を作成 |
| Edit Works List | ワークスポータルの接続先を管理 |
部屋を公開する
公開手順
- コンテキストメニューから Export ZIP を選択
- ダウンロードされた ZIP を解凍すると
public/フォルダが入っています public/フォルダをサーバー上の部屋ディレクトリにコピーします:
room/
├── index.html
├── app.js
├── style.css
├── js/
├── assets/
└── public/ ← エクスポートされたフォルダ
└── manifest.json
public/ フォルダが存在すると、自動的に 公開モード(訪問者は閲覧のみ)になります。
公開を取り消す
public/ フォルダを削除するか、public/manifest.json を削除またはリネームしてください。
外部からのアクセスは manifest.json の有無で判定されるため、ファイルがなければ部屋にアクセスできません。
公開中に再編集する
/(スラッシュ)キーを押すと、公開モード中でも編集モードに切り替えられます。
ポータルシステム
部屋同士はポータルで接続されます。GitHub に置かれた portal_list.json が公開ディレクトリとして機能します。登録は Pull Request で行い、マージされると公開されます。サーバーは不要です。
ポータルに入ると、プロシージャル生成された広場が表示され、接続先のポータルがバナー画像やテキストラベル付きで並びます。
3種類のポータル
| タイプ | 色 | データソース | 用途 |
|---|---|---|---|
| Global | 緑 (#00ff88) | GitHub の portal_list.json | 公開ディレクトリ — 全 ROOM が参照 |
| Friend | 青 (#4488ff) | localStorage / エクスポート ZIP | 特定の相手だけに見えるプライベートリンク |
| Works | 黄 (#ffaa00) | localStorage / エクスポート ZIP | 自分の作品群を繋ぐ内部リンク |
Friend ポータルと Works ポータルは、コンテキストメニューの Edit Friend List / Edit Works List から管理します。各エントリには名前、URL、バナー画像、説明文を設定できます。
バナー画像の仕様
| 項目 | 推奨値 |
|---|---|
| サイズ | 480 × 120 px(4:1) |
| 形式 | WebP または PNG |
| 容量 | 30KB 以下 |
| CORS | Access-Control-Allow-Origin: * が必要 |
バナー画像が読み込めない場合はテキストラベルにフォールバックします。
[
{ "name": "lain's room", "url": "https://lain-lab.com/room/", "image": "https://lain-lab.com/room/banner.webp","description": "メインルーム。VRMフィギュアとポータル" },
{ "name": "GitHub Pages room", "url": "https://fixtan.github.io/WIRED_ROOM/", "image": "https://fixtan.github.io/WIRED_ROOM/banner.webp", "description": "GitHub Pages TECHNICAL LOGS & DEMOS" },
{ "name": "Vercel Pages room", "url": "https://room-vercel.vercel.app/", "image": "https://room-vercel.vercel.app/banner.webp", "description": "Vercel Pages TECHNICAL LOGS & DEMOS" },
{ "name": "Cloudflare Pages room", "url": "https://room-cloudflare.fixjp.workers.dev/", "image": "https://room-cloudflare.fixjp.workers.dev/banner.webp", "description": "Cloudflare Pages TECHNICAL LOGS & DEMOS" },
{ "name": "Render Pages room", "url": "https://room-render.onrender.com/aisle/", "image": "https://room-render.onrender.com/aisle/banner.webp", "description": "Render Pages TECHNICAL LOGS & DEMOS" }
]
部屋を登録する
グローバルポータルディレクトリに自分の部屋を登録するには、 https://lain-lab.com/contact からルーム名、URL、バナー画像を送ってください。
CORS 設定
部屋間のポータル移動には、サーバーが CORS ヘッダーを返す必要があります。
.glb、.vrm、.vrma、メディアファイルに対して以下のヘッダーが必要です:
Access-Control-Allow-Origin: *
ホスティングサービス別の設定
GitHub Pages — 設定不要。デフォルトで CORS が有効。
Netlify — ルートに _headers ファイルを追加:
/*
Access-Control-Allow-Origin: *
Cloudflare Pages — Netlify と同じ。ルートに _headers ファイルを追加。
Vercel — ルートに vercel.json を追加:
{
"headers": [
{
"source": "/(.*)",
"headers": [
{ "key": "Access-Control-Allow-Origin", "value": "*" }
]
}
]
}
※ Vercel はデフォルトで public/ を出力ディレクトリにするため、Settings → Build and Deployment → Output Directory を . に変更してください。
Render — ルートに _headers ファイルを追加(Netlify と同じ形式)。
Apache — .htaccess に追加:
Header set Access-Control-Allow-Origin "*"
nginx — server ブロックに追加:
add_header Access-Control-Allow-Origin "*";
バックアップと復元
部屋のデータはブラウザ内(localStorage + IndexedDB)に保存されます。Export/Import ZIP でバックアップと復元ができます。
バックアップ — Export ZIP で完全な部屋の状態を保存。部屋 GLB、配置メディア(画像・動画)、VRM フィギュア(ポーズ付き)、クレジットボード、ポータル配置、すべての座標とスケールが含まれます。
復元 — Import ZIP で以前の状態に復元。現在のデータは上書きされるため、事前にバックアップを取ってください。
部屋の切り替え — 現在の部屋を Export ZIP でバックアップ → Clear All Data → 別の ZIP を Import。
データ保存先
localStorage(軽量メタデータ)
| キー | 内容 |
|---|---|
room_config | ウィザード設定(roomId, avatarId, skyPreset 等) |
room_media | メディア配置のメタデータ配列 |
friend_portal_list | フレンドポータルの接続先リスト |
works_portal_list | ワークスポータルの接続先リスト |
IndexedDB: RoomDB.assets(バイナリ・大容量データ)
| キーパターン | 内容 |
|---|---|
custom_room_* | カスタム GLB バイナリ |
custom_vrm | カスタム VRM バイナリ |
media_<id> | 画像(base64)/ 動画(ArrayBuffer) |
meta_custom_room_* | 部屋メタ情報(名前、作者、ライセンス、サムネイル、ポリゴン数) |
meta_room_<roomId> | プリセット部屋のメタ情報 |
技術スタック
| 技術 | 用途 |
|---|---|
| Three.js (r170) | 3D レンダリング |
| @pixiv/three-vrm | VRM アバター対応 |
| three-mesh-bvh | BVH レイキャスト衝突判定 |
| Dexie | IndexedDB ラッパー |
| WebXR | Meta Quest VR モード |
ビルドツール不使用。importmap + CDN で依存を解決しています。
設計思想
サーバーは作らない。 静的ファイルで完結します。動的なバックエンドに依存しません。
荒らす場所を作らない。 中央サーバーがないので、他人の空間を荒らす手段がありません。各自が自分のサーバーに自分の部屋を持ちます。
ビルドツール不要。 importmap + CDN で Three.js やライブラリを読み込みます。package.json もない。
データ駆動。 room.json / manifest.json がすべてを定義します。コードを書き換えなくても、JSON を編集すれば部屋が変わります。
段階的に進める。 動くものを先に出す。完璧を目指して止まるより、使えるものを公開して改善する。
ソースコード
GitHub: https://github.com/fixtan/WIRED_ROOM
ライセンス: MIT