build-threejs-scroll-worlds について
空間の連続性と操作性が必要な体験向けに、Three.js のリアルタイムなスクロールストーリーを構築する開発スキルです。持続するワールドと可逆なスクロール状態で、カメラ、照明、フォグ、アニメーション、章構成を制御します。
主な機能
- 01持続する Three.js シーン構成
- 02ネイティブスクロールによる可逆状態
- 03章ごとのシーンとカメラ設計
- 04照明、フォグ、アニメーションの補間
- 05レイキャスト操作とライフサイクル管理
活用シーン
- 01リアルタイム 3D 製品ストーリーの制作
- 02スクロール駆動の空間的な章体験の構築
- 03シーン素材、性能予算、品質検証の計画
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mengto/ skills --skill build-threejs-scroll-worldsインストール後、Claude Code で/build-threejs-scroll-worldsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
agents/openai.yamldemo/index.htmlPROMPT.mddemo/secret-pathways-assets/fonts.cssreferences/kage-anatomy.mdquality-and-qa.mdrealtime-architecture.mdscroll-conductor.jsworld-bible.md詳細
Three.js のスクロールワールドを構築する
詳細なリアルタイムワールドを一つ構築し、ネイティブなドキュメントスクロールを決定論的な指揮役として使います。カメラの構図、ライト、フォグ、アニメーション、コピー、インタラクションの焦点を、作り込んだチャプターに沿って移動させながら、レンダラー、シーングラフ、空間の連続性を維持します。
仕組みは、永続する一つの Three.js ワールド + 正規化された一つの可逆スクロール状態です。どちらかを取り除くと、体験が積み重ねたセクションへと崩れてしまうなら、このスキルが適しています。
正確な Kage デモが品質基準を示しています。これは演出例であり、題材やレイアウトを必須とするものではありません。依頼された方向性に役立つ場合に限り、詳細な構成をreferences/kage-anatomy.mdで参照してください。
リクエストを適切に振り分ける
- スクロールで演出する旅がなく、インタラクティブなシーンが一つだけの場合は、
threejsを使用します。 - リアルタイム3D、プリレンダリング動画、DOM主体のストーリーテリングから選ぶ場合は、
scroll-world-storytellingを使用します。 - スクロールで時間を操作する動画または画像シーケンスには、
scroll-scrubbed-visual-sequenceを使用します。 - DOM主体のGSAP/Lenisによる演出には、
cinematic-scroll-storytellingを使用します。 - オブジェクトが本当に空間内に存在してインタラクティブであり続け、スクロールによって一つのライブWebGLワールド内の複数の構図を巡る必要がある場合は、このスキルを使用します。
動画をThree.jsに見せかけてはいけません。公開されているoso95/scroll-worldプロジェクトは、コミット71cc36dで確認されており、要件の把握、シーン台帳、予算ゲート、モバイル固有の構図、設定駆動の再生、シームのQAに関する優れた参考例です。ただし、そのレンダラーは事前生成された動画チェーンです。このスキルでは、構造上の強みを取り入れつつ、実際のジオメトリ、マテリアル、ライティング、レイキャスト、カメラ制御を維持します。
構築リファレンスを読む
新しいワールドを実装する前に、以下を読んでください。
- references/world-bible.md:要件の把握、アートディレクション、シーン、マテリアル、テクスチャ、インタラクションの各台帳。
- references/realtime-architecture.md:シーングラフ、指揮役、カメラ、読み込み、インタラクション、ライフサイクルのパターン。
- references/quality-and-qa.md:最適化と最終検証の前に確認します。
フレームワーク固有の実装ではなく、移植可能なネイティブスクロールの指揮役が必要なプロジェクトでは、references/scroll-conductor.jsをコピーしてください。
テンプレートではなく、出力から始める
ワールドの用途を見極めます。ランディングページ、ポートフォリオ、博物館のチャプター、製品解説、ゲームの予告、エッセイ、データストーリー、あるいは別の空間体験でしょうか。すべての依頼をヒーロー+CTAのレイアウトに当てはめてはいけません。
不明な点だけを確認します。
- 題材、対象ユーザー、順序立てたストーリー展開。
- アートディレクションと感情の展開。
- ワールドが連続しているか、ポータルでつながっているか、隣接するセットで構成されているか。
- 対象デバイスと最低限許容できるハードウェア。
- スクロール以外で、ワールドにどの程度のインタラクティブ性を持たせるか。
- 利用可能なモデル、テクスチャ、ブランド素材、音声、コピー。
- 初回読み込みとダウンロード総量の予算。
承認済みのリファレンスや動作するシーンがユーザーから提供されている場合は、まずそれを調査し、実際のジオメトリ、マテリアル、テクスチャ、ライト比、カメラ値、モーション定数を台帳に反映します。測定された詳細を形容詞に置き換えてはいけません。
コードを書く前にワールドバイブルを作成する
再利用できる一貫したビジュアル文法を定義します。
- スケール体系と単位の規約。
- シルエットの表現と様式化の度合い。
- パレットとチャプターごとのアクセントの変化。
- マテリアルの系統と経年変化のルール。
- キーライト、フィルライト、リムライト、実用灯、発光ライトの役割。
- フォグ、ヘイズ、パーティクル、天候、ポストプロセッシング。
- タイポグラフィ、DOM構成、近クリッピング面の前景ルール。
- カメラ、環境オブジェクト、インタラクションのモーション文法。
目に見えるすべてのディテールは、同じワールドを支える必要があります。ランダムなノイズ、無関係なテクスチャパック、場当たり的なパーティクル効果、使い捨てのマテリアルは、一貫性のないまま複雑さだけを増やします。
シーン台帳を作成する
ほとんどの体験では、チャプターを4〜8個にします。しきい値をCSSやレンダーループに散在させず、契約全体をデータとして保存します。
const chapters = [
{
id: "threshold",
scrollWeight: 1.25,
copy: {
eyebrow: "Chapter 01",
title: "Enter the archive",
body: "A spatial collection revealed through motion."
},
camera: {
position: [0, 3.8, 13.5],
target: [0, 2.4, -8],
fov: 38,
mobile: { position: [0, 4.8, 18], fov: 46 }
},
world: {
key: 1.0,
practicals: 0.35,
fog: 0.018,
particles: 0.25,
grade: "cold"
},
focus: ["gate", "lantern-left"],
interactions: ["inspect-gate"],
assets: ["gate-shell", "stone-1k", "mist-atlas"]
}
];
各チャプターには、ストーリーの要点、ランドマーク、カメラの終点、遮蔽物、ライト/フォグの状態、有効なアニメーションクリップ、インタラクション対象、DOMの要点、前景の演出、アセットの依存関係、レスポンシブ時のオーバーライドを記録します。コピーだけが異なるチャプターは却下します。
持続性のある空間アーキテクチャを1つ構築する
以下のシステムを一度だけ作成します。
WebGL canvas
worldRoot
environment sky, terrain, distant silhouettes
architecture persistent landmarks and paths
chapterSets local props grouped for culling and loading
interactives raycast targets and animation state
atmosphere fog volumes, particles, weather
nearPlane3D optional camera-relative depth accents
DOM above canvas
semantic chapters headings, copy, links, media, fallback order
fixed interface progress, chapter navigation, controls
fixed cut-outs optional alpha foregrounds at viewport edges
レンダラーは1つにし、通常はシーンも1つにします。透明度、ポストプロセス、インタラクションの分離が必要な場合は、レイヤーまたはレンダーパスを使用します。チャプターごとにレンダラーをインスタンス化したり、場面のつなぎ目で世界を作り直したりしないでください。
トポロジーは意図的に選びます。
- 連続した地理: ランドマークが1つの移動可能な空間を共有します。存在感は最も強く、ワールド構築のコストも最も高くなります。
- 接続されたセット: 部屋や島を、トンネル、門、霧、地形の起伏、暗闇でつなぎます。アートディレクションとストリーミングが最も容易です。
- レイヤー状の展開: 同じ場所を、時間、スケール、状態の変化によって見せます。無関係な座標へ移動するのではなく、マテリアル、可視性、ライトをアニメーションさせます。
避けられない不連続は、遮蔽、暗闇、濃い大気、屋内への境界、または手前を通過するオブジェクトで隠します。開けた空間でオブジェクトが目に見えて瞬間移動することは、決して避けてください。
世界に本物のディテールを与える
ジオメトリ
- まず大きなシルエットを定め、次に中規模の形状、最後に小さなアクセントを加えます。小道具を細かく大量に散らしても、弱いシルエットは補えません。
- 建築物のエッジには、もっともらしい厚み、面取り、継ぎ目、キャップ、段差、接点を設けます。紙のように薄い屋根や浮いた小道具は、作り物だとすぐに露呈します。
- 固有のジオメトリを重複させるのではなく、モジュラーキット、インスタンシング、静的メッシュの結合、LODを使用します。
- 無制限のランダム化ではなく、作り込んだクラスター、スケール/回転の範囲、デカール、マテリアルの変化で反復を崩します。
- コリジョン用およびレイキャスト用のプロキシは、レンダーメッシュよりシンプルに保ちます。
マテリアルとテクスチャ
画像の改善に役立つ場合は、一貫性のあるPBRサーフェススタックを使用します。
| マップ | 役割 | よくある失敗 |
|---|---|---|
| ベースカラー | マテリアルの識別と大まかな変化 | 焼き込まれたハイライトが動的ライティングと競合する |
| ノーマル | 小さな方向性のある凹凸 | 強度が高すぎるとゴムや箔のようになる |
| ラフネス | ハイライトのばらつきと経年変化を制御する | 値が一律だと、すべてのオブジェクトがプラスチックのようになる |
| AO | 接触部や隙間を地面になじませる | 強く乗算しすぎると、継ぎ目が汚れて見える |
| メタルネス | 導体と誘電体を区別する | あらゆる場所にグレー値を使うと、不自然に濁る |
| エミッシブ | 実用照明、画面、ルーン | ライトの代わりにはなるが、近くの形状は照らさない |
| アルファ/透過 | 葉、布、ガラス、霧 | ソート、オーバードロー、深度アーティファクト |
- カラーテクスチャはsRGBに設定し、ノーマル、ラフネス、AO、メタルネス、データテクスチャはリニアに保ちます。
- カメラの範囲内ではテクセル密度を一貫させます。フレームを実際に占めるサーフェスには2K〜4Kのマップを使い、ほとんどの小道具には512〜1Kのアトラスを使います。
- 適切な場合は、KTX2/Basis圧縮、Meshopt/Dracoジオメトリ圧縮、アトラス、トリムシート、デカール、ベイク済みAO/ライトを優先します。
- 異方性は、浅い角度から見る必要があるサーフェスにだけ追加します。すべてのテクスチャを最大値に設定すると、帯域幅を無駄にします。
- 摩耗には原因を持たせます。露出したエッジは磨かれ、くぼみには汚れがたまり、水は縦筋や水たまりの跡を残し、道では植生が踏み固められます。一様な汚れはフィルターのように見えます。
- 葉には、透明ブレンドの平面より先に、アルファテスト付きカードやインスタンス化したローポリのクラスターを使います。透明度によるオーバードローは、ジオメトリより高コストになることがよくあります。
ライティングと雰囲気
- 作り込んだキーライトを1方向から当て、環境光/フィルライトは控えめにし、実用的な発光源を加えるところから始めます。目に見える関係性を生み出す場合にのみ、ライトを追加します。
- 可能な場合は、静的なバウンスライトとコンタクトシャドウをベイクします。プロファイリングでそれ以上が妥当と確認できない限り、シャドウを投影する動的ライトはモバイルで1~2個、デスクトップで2~4個程度に抑えます。
- フォグやヘイズは、シーンを暗くするだけではなく、奥行きの面を分離するために使います。焦点となるランドマークはコントラストの範囲内に保ちます。
- 発光するジオメトリ、グロースプライト、実際のライト強度、ブルームのしきい値を調整し、画面全体を白飛びさせずにランプが発光して見えるようにします。
- 未処理のフレームを構成してから、ポストプロセスを適用します。ブルーム、ビネット、グレイン、色収差、被写界深度によって、素材やフレーミングの弱点を覆い隠してはいけません。
詳細な表面とライティングの計画は、references/world-bible.md の台帳に記録してください。
ネイティブスクロールを決定論的な状態にマッピングする
フォントと重要なメディアの読み込みが落ち着いてから、安定したセクションアンカーを測定します。scrollY を 2.35 のような小数のチャプター値に変換します。
次の値を個別に保持します。
rig.target = progressFromScroll(scrollY); // exact reproducible story state
rig.smooth = reduceMotion
? rig.target
: damp(rig.smooth, rig.target, 5.2, dt); // cinematic render state
ナビゲーション、URL、アクセシビリティ、フォアグラウンドの所有権、操作の制御には正確な進行度を使用します。カメラとビジュアルの補間にのみ、平滑化した進行度を使用します。同じスクロール位置では、前後どちらにスクロールした場合も、高速ジャンプした後も、再読み込み後も、同じ状態が再現される必要があります。
基本実装には references/scroll-conductor.js を使用してください。ネイティブスクロールを信頼できる唯一の情報源として維持し、ホイールの差分をストーリー位置に積算してはいけません。
カメラをシネマトグラフィーとして設計する
補間する前に、デスクトップとモバイルの両方で、各チャプターの終点の構図を決めます。
- 位置、ターゲット、FOV、必要に応じてロール、レンズシフト、レスポンシブ用の上書きを保存します。
- 広く連続した移動には Catmull–Rom 曲線を、意図的なターンにはセグメント補間を使用します。
- 曲線が壁を突き抜けないか、地面に食い込まないか、ターゲットが反転しないか、速度が急上昇しないか、意図しない至近距離の通過がないかを確認します。
- ストーリーのペースを意図どおりに保つため、生の曲線の弧長ではなく、チャプターの進行度をパラメーターにします。
- 重要なビューをより長く見せるには
scrollWeightを使います。セクションを遅くするためだけにカメラパスを歪めてはいけません。 - 基本の構図が機能してから、控えめなポインターパララックスを加えます。動きを制限し、精密なトランジションの近くでは徐々にブレンドアウトします。
- 縦長のビューポートでは、任意の中央クロップを受け入れるのではなく、引きのカメラ移動やFOVの上書きを設計します。
カメラの動きによって、新しい空間的な関係性を見せる必要があります。接近、登場、通過、スケール変化、観察、地平線、離脱です。同じ中心に向けたドリーインを6回行っても、6つのシーンにはなりません。
同じコンダクターからワールドの状態を補間する
フレームごとに隣接するチャプターを一度だけ特定し、宣言された値を補間します。
const { a, b, t } = segmentState(rig.smooth);
moon.scale.setScalar(lerp(a.world.moon, b.world.moon, t));
key.intensity = lerp(a.world.key, b.world.key, t);
scene.fog.density = lerp(a.world.fog, b.world.fog, t);
オクルージョン、マテリアルのブレンド、アニメーションミキサーのウェイト、ライト、フォグ、スケール、トランスフォームなど、連続的な物理変化を優先します。アセットを入れ替える場合は、オクルージョンのある区間、または大気の密度が高い区間でのみクロスフェードし、トランジションが完了するまで両方の状態を読み込んだままにします。
スクロールを妨げずにインタラクションを追加する
スクロールは大きな移動を担います。ポインター、タッチ、キーボードのインタラクションは、局所的な応答を担います。
- すべての装飾的な三角形ではなく、名前付きのプロキシメッシュに対してレイキャスティングを行います。
- 各インタラクティブオブジェクトに
idle、hover、focused、active、unavailableの状態を定義します。 - ホバー時には、ライトを強めたり、マテリアルの反応を変えたり、ラベルを表示したり、短いアニメーションを再生したりします。スクロールカメラを経路から外してはいけません。
- ユーザーがコントロールをドラッグしたり、ホットスポットを有効にしたりしている間は、ポインターの視差効果を一時停止するか、弱めます。
- インタラクションは、チャプターの正確な表示状態と深度に基づいて制御します。非表示のオブジェクトはイベントを捕捉してはいけません。
- すべての重要なホットスポットに、文書上の順序に沿った DOM ボタンまたはリンクを用意します。視認できるフォーカス状態を設け、状態を 3D オブジェクトと同期させます。
- タッチ操作では、誤操作による影響が大きい場合、タップでフォーカスし、もう一度タップして有効にします。DOM プロキシのヒット領域は、少なくとも 44 CSS px にします。
- 装飾的なパーティクルトレイルやカーソル効果はオプションにし、適切な場合はカメラ相対にして、粗いポインターや視差効果を抑制する設定では無効にします。
実装前にインタラクションマトリクスを作成し、references/world-bible.md のパターンを使用します。
DOM のストーリーをセマンティックに保つ
見出し、本文、リンク、コントロール、フッターは、キャンバスの上または横に実際の HTML として配置します。3D の世界は場所を作り、DOM は意味とフォールバック時の順序を担います。
- リズムを高める場合に限り、見出しを単語ごとに表示します。完全なアクセシブルラベルは保持します。
- アイブロウ、見出し、本文、メディア、実績、CTA は、それぞれ独立したビートとして表示します。
- カメラが大きく移動する間も、本文ブロックを安定させます。
- 固定アルファ切り抜きはオプションの前景面の風景として使用し、すべてのデザインに必須としないでください。使用する場合は、アクティブな間は完全に不透明にし、表示の主導権が移った後にフェードアウトまたはぼかします。
段階的に読み込む
旅全体を読み込む前に、最初に作成したフレームを完成させます。
- 重要なシェル、カメラ、最初のシーンのジオメトリ、最小限の環境、フォールバック用ポスターをインライン化するか、先行読み込みします。
- 次のチャプターが表示範囲に入る前に読み込みます。1〜2 チャプター先まで先行取得します。
- インタラクションのメイン処理経路とは別にテクスチャをデコードし、必要なアセットの準備ができた場合にのみチャプターを表示します。
- WebGL、モデル、テクスチャの読み込みに失敗した場合も、デザインされたポスターとセマンティックな DOM を表示したままにします。
- 恣意的なタイマーではなく、必要なアセットのサイズまたは完了したグループに基づいて、意味のある進捗を報告します。
40 MB の世界を装飾的なパーセンテージ表示の裏に隠してはいけません。アセット台帳に読み込み計画を記録します。
測定可能なパフォーマンス予算を維持する
まず次の予算を目安にし、実際の対象デバイスでプロファイリングします。
| 予算 | モバイルの目標 | デスクトップの目標 |
|---|---|---|
| DPR 上限 | 1.25–1.5 | 1.5–2 |
| 表示中の三角形数 | 150k–300k | 500k–1.2m |
| ドローコール数 | 50–90 | 90–160 |
| 影を落とすライト | 1–2 | 2–4 |
| 同時にブレンドする全画面レイヤー | 2 | 3 |
| 初回の重要な転送量 | 3–6 MB | 5–10 MB |
| 安定時のフレーム時間 | 理想は ≤16.7 ms、フォールバックは ≤25 ms | ≤16.7 ms |
これらは初期の目安であり、成功を保証するものではありません。CPU、GPU、テクスチャメモリ、シェーダーのコンパイル、長時間タスク、初回のインタラクティブフレームを測定します。
- 停止後は
dtをおよそ1/30秒に制限します。 document.hiddenのとき、およびエクスペリエンスが表示されていないときは一時停止します。- 作成済みのランドマークを削除する前に、DPR とオプションのエフェクトを下げる品質制御機構を使用します。
- セカンダリカメラ、反射、クロスシミュレーション、高負荷のパーティクルは、必要な間だけ描画します。
- 終了処理では、ジオメトリ、マテリアル、テクスチャ、レンダーターゲット、オブザーバー、イベント、アニメーションミキサー、RAF を破棄します。
モーション、アクセシビリティ、障害への配慮
- ブラウザー標準の可逆なスクロールを維持してください。ホイール操作を妨げたり、カスタムスクロールバーを強制したりしないでください。
- 視差効果を減らす設定では、カメラ/状態を最も近い構成済みチャプターにスナップさせ、環境ループやスタッガー/ぼかしを停止し、順序立てて構成された DOM ストーリー全体を維持してください。
- 適切な見出し階層、ランドマーク、リンク、フォームコントロール、視認できるフォーカス、到達可能なフッターを維持してください。
- WebGL を利用できない場合に備えて、構成済みのポスターまたはチャプターの静止画を用意してください。
- 背景の世界が変化しても、コピーのコントラストを維持してください。シーン全体を不透明なレイヤーで覆うのではなく、作成したスクリーンや局所的なコントラスト調整を使用してください。
体験全体を検証する
references/quality-and-qa.md に従ってください。最低限、次の項目を検証してください。
- 1440×900、768×1024、390×844 での各カメラ終点;
- ゆっくりしたスクロール、高速スクロール、逆方向へのスクロール、スクロールバーのドラッグ、アンカー移動、深い位置での再読み込み、チャプター間のサイズ変更;
- マテリアルのスケール、UV、テクスチャの色空間、粗さの反応、接地表現、影の安定性、フォグの深度、ポストプロセッシング;
- ホバー、フォーカス、タップ、アクティブ化、チャプターのゲーティング、スクロールで離れて戻った後の操作復帰;
- 初回読み込み時のポスター、段階的なチャプター読み込み、アセットの読み込み失敗、コンテキスト喪失、非表示タブからの復帰、ティアダウン;
- 視差効果を減らす設定、WebGL フォールバック、キーボード操作順、読みやすい DOM、到達可能なフッター、クリーンなコンソール;
- 対象デバイスでのフレーム時間、ドローコール数、三角形数、テクスチャメモリ、転送サイズ、シェーダーのコンパイル。
視覚と操作の検証には Codex ブラウザーを使用してください。ビルド/DOM のチェックは視覚的な証明にはなりません。
成果物
次を提出してください。
- ワールドバイブルとアートディレクションの定数;
- チャプター、カメラ、マテリアル/テクスチャ、操作、アセット、パフォーマンスの台帳;
- レイヤーとシーングラフのマップ;
- 動作するエクスペリエンスとローカル実行時アセット;
- 代表的なチャプターのデスクトップ、タブレット、モバイルでの検証資料;
- 測定済みのパフォーマンスと読み込み結果;
- フォールバック/視差効果を減らす設定の検証資料;
- 残る視覚、操作、デバイスの課題を明確に記載したもの。
ユーザーがリファレンス自体の修正を明示的に求めない限り、同梱の Kage デモは変更しないでください。