3D空間に自分の”島”をつくって遊べるサービスを作った

Tech

Three.jsでブラウザに3D空間を作る

「うかぶしま(Ukabushima)」という、WebGLで作成した3Dの浮かぶ島にオブジェクトを配置して遊べるWebサイトを作りました。

https://ukabushima.tmkst.com/

自分の島はこちらです👉@tmkst

今回はこのプロジェクトについて紹介します。設計~実装は9割Claude Codeです。

概要

ユーザーは好きなようにオブジェクトを配置したり、ひとりごとを書いたり、音楽を設定したりできます。
自分の空間として楽しんでもらうことが前提なので、フォローやいいね機能などはありません。

公開設定にすると、リンクの共有で島を覗きに来てもらうこともできます。
「ほかの島を探す」ページにも表示されるので、知らないユーザーが自分の島に訪れたり、逆に他の島を見ることもできます。

また、春は桜が降ったり夕方になると空が暗くなったり、時間帯や季節に応じて景色が変化します。

技術構成

技術構成はこんな感じです。

カテゴリ 技術 備考
3Dレンダリング Three.js + React Three Fiber
3Dアセット Kenney.nl(GLTF) CC0・無料
UIフレームワーク React + Vite + TypeScript
音楽 Spotify / Apple Music 埋め込み iframeウィジェット
BaaS Supabase Auth・PostgreSQL、無料tier
ホスティング Cloudflare Workers + Assets
PWA vite-plugin-pwa manifest・SW自動生成

CloudflareとSupabaseで無料でホスティングしています。

3DアセットはKennyのアセットを使用しており、CC0(パブリックドメイン)のため自由に使用できます。
ローポリの可愛い雰囲気はこのアセットのおかげです。。これが完全無料なのすごい。

ポイントいろいろ

1. Three.js / React Three Fiberによる3D描画

3DレンダリングにはReact Three Fiberを使用しています。

カメラ操作を制御して、「空に浮かぶ島を見下ろす」という世界観を担保しています。

GLBの読み込みはuseGLTF + useMemoでインスタンスをメモ化しています。
useGLTFはGLB/GLTFモデルを非同期に読み込み、シーンやメッシュ、マテリアルへ簡単にアクセスできるフックです。

キャラクター・動物についてはSkeletonUtils.clone()(three.jsのAPI)で骨格ごとにディープコピーしています。
これにより、同じGLBモデルを複数配置してもそれぞれが独立してアニメーションできるようになります。

2. 時刻・季節による動的ライティング

時間帯を4つの区分に分け、空のグラデーション色、DirectionalLight(太陽のように一定方向から当たる光)の色と強度、AmbientLight(全体を均一に照らす環境光)の色と強度を変更しています。

夜にライティングを暗くするとアセットがほぼ真っ暗になってしまうため、AmbientIntensity(環境光の明るさ)を上げて視認できるようにしています。

編集画面ではスライダーで時間帯ごとの見え方のプレビューも可能です。

3. パーティクルシステム(季節エフェクト)

パーティクルシステムとは、数多くの小さな画像やメッシュ(パーティクル=粒子)を発生・操作し、炎、煙、液体、魔法のような複雑な視覚エフェクトをシミュレートする技術です。
three.jsではこれをPointsやシェーダーなどを使って表現できます。

春は桜、秋は落ち葉、冬は雪、のように季節別のパーティクルをループしています。
(夏は降らせるものが思いつかなかったのでなしです。代わりに島の緑が少し濃くなります🍃)

4. 島の形バリエーションと地形高度

島の形も「標準」「丘の島」「池の島」「双子島」の4種類から選べるようになっています。

丘の島は座標から高度を動的に計算して配置オブジェクトが丘の斜面に追従するようにし、双子島では隣の小さい島にも配置できるようにしています。

5. Supabaseの認証・RLS設計

DBはSupabaseのRLS(Row Level Security)を有効にし、ユーザーごとにアクセスできるデータを制御しています。

RLSとはテーブルの行単位でアクセス権限を設定できる仕組みで、ユーザー自身のデータのみに操作を制限できます。
このRLS自体はPostgreSQLの機能で、Supabaseは内部でPostgreSQLを使っているので、そのRLSをそのまま使いやすく提供している、というイメージです。

認証にはSupabase Auth(メール/パスワード)を使用しています。

また、島オブジェクトの保存は差分更新ではなく「全削除 → 全挿入」とし、RLSのポリシーに沿った形でシンプルな保存ロジックにしています。

6. 音楽の実装

BGMはSpotify / Apple MusicのURLを貼り付けるとiframe埋め込みウィジェットを表示する仕組みになっています。

Howler.jsでBGMを再生する形にしたかったんですが、Spotify / Apple Musicの音源はライセンスやAPIの制約により直接再生できないため、iframeによる埋め込み表示にしています。

7. デプロイ構成

デプロイにはCloudflare Workersを使用しています。

無料枠がかなり充実しているので個人利用にはありがたいです。


余談ですが本サイトにAboutWorksページを追加しました。

Worksには今回紹介したUkabushimaも掲載してみました。
Product HuntとかHacker Newsにも投稿してみるか迷い中。。