写真級室内シーン(総綱)
このスキルは、以下のスキルを一連のフローにまとめ、直接実行可能なプロジェクトテンプレートを提供します。 手法は room-at-dawn(MIT)に基づいています。朝の寝室をすべてプログラムで生成し、ブラウザ上で動作させます。元のプロジェクトの規模はおおよそ以下の通りです:
- 183万トライアングル、ロード約7秒(RTX 4090)。
- ベイクされたライティングファイル
gi.bin約13 MB、ベイク時間約30分。 - 動画は4K HDR10。
各ステップで使用するスキル
| ステップ | スキル | 成果物 |
|---|---|---|
| 0 | 3d-spec-prompt | アイデアを検証可能な仕様書に:雰囲気、時間、スケール、主要オブジェクト、カメラ |
| 1 サイズと外殻 | 本スキルの template/src/layout.js、parts/room.js | 実寸(メートル)、窓、壁厚、外殻 |
| 2 主要オブジェクト | threejs-procedural-cloth(布団、毛布、カーテン)、threejs-procedural-vegetation(窓の外の木)、threejs-procedural-pothos(室内の植物) | 視線の焦点となるオブジェクト |
| 2b 空と窓外 | threejs-sky-backdrop(空のプリセット、雲、窓外の芝生、家、遠方の生け垣、見えるものだけを構築) | ベイクと画面の両方に同じ空を使用 |
| 3 マテリアル | threejs-procedural-textures | 壁、床、木、織物、使用感、本のカバー |
| 4 小物 | threejs-lived-in-props | 椅子の背にかけた布、コップ、ポット、靴下、電線、紙くず |
| 5 ライティング | threejs-baked-gi | 天光と太陽の反射光を頂点にベイクし、gi.bin として保存;太陽の直接光はリアルタイムライトを使用 |
| 6 画面 | threejs-realtime-post | AO、ブルーム、窓外と室内の露出を個別に調整、カラーグレーディング |
| 7 検証、録画 | webgl-deterministic-recording | スクリーンショット回帰テスト、フレームごとのレンダリング、映画出力(被写界深度、モーションブラー、HDR10) |
新規プロジェクト作成
bash <スキルフォルダ>/scripts/new-project.sh ~/git_project/my-room
cd ~/git_project/my-room && python3 -m http.server 5430 --bind 127.0.0.1
# http://127.0.0.1:5430/ すでにベイク済みの bake/gi.bin が同梱されています
# http://127.0.0.1:5430/?bake=128 シーンを変更した後に再ベイクし、「gi.bin をダウンロード」して bake/ に保存
(<スキルフォルダ> はこのスキルをロードしたときに表示されるベースディレクトリです。プラグインとしてインストールされている場合は ~/.claude/plugins/cache/ 以下にあります。)
- このスクリプトはテンプレートをコピーし、各サブスキルのライブラリを
src/lib/にコピーします(gi、post、props、textures、cloth、vegetation、pothos、sky、film)。プロジェクトはこれで独立して動作します。 - バンドルツールは不要で、npm も使いません。
threeとthree-mesh-bvhは jsdelivr からロードされます。 - URL パラメータ:
?cam=:カメラ位置(room、desk、window、corner、view=窓辺に立って外を見る)。?t=:時間固定(葉や雲が動かない、スクリーンショット用)。?view=gi:ライティングのみ表示。?only=furniture:特定のパーツのみ構築。?exp=:露出。
- ページには
window.__ready、window.__stats、window.__cameraが用意されており、webgl-deterministic-recordingのツールに直接接続できます。 - 操作:ドラッグで視点回転;WASD/矢印キーで移動(Shift でゆっくり歩く、壁や家具に衝突します);画面をクリックでマウスでの直接ヘッドトラッキングに切り替え、視線の高さが1.6mになります(Esc で解除)。オービットモードではカメラと注視点は部屋内に制限され、引きやパンで壁を超えることはありません。
テンプレートの構造:
| ファイル | 内容 |
|---|---|
src/layout.js | サイズ、太陽、空(SKIES プリセット)、窓外設定(OUTSIDE)、カラーパレット、カメラ、すり抜けられない家具範囲(BLOCKERS)を唯一記述する場所 |
src/materials.js | lit()(GI パッチ、元のシェーダーパッチを保持、アルベドを記録)、solid()、tbox()、tplane()、metres() |
src/scene.js | order に従って各パーツを構築、順序は固定 |
src/parts/room.js | 床、天井、四面の壁、窓穴と窓台、黒い外殻、壁芯 |
src/parts/outside.js | 窓外:天空球、芝生、砂利道、生け垣、家、遠方の樹壁、主要な木と中~遠景の木(見えるものだけを構築、threejs-sky-backdrop + threejs-procedural-vegetation)。すべて gi = false、ベイク光を妨げない |
src/parts/furniture.js | 机、椅子、椅子の背にかけたタオル(PBD)、コップ、ポット、机の上の本、本棚の本 |
src/main.js | シーン構築 → ベイク、ファイル読み込み or フラットライト → 太陽 → 反射 → ポストプロセス → カメラ(オービット+移動、部屋内に制限) |
スキル間の絶対ルール
- 単位はメートル、座標は固定。 X は窓壁に沿って、Z は室内方向(窓壁は z = 0、z < 0 は室外)、Y は上。すべてのサイズは
layout.jsにのみ記述。 - 決定論的。 乱数はすべて
RNG(seed)を使用。パーツの順序、名前、頂点数が1つでも変わると、そのメッシュのベイクは無効になります。applyBakeは古いデータを報告します。 - 光は頂点に乗るため、細分化が必要。 何かが置かれる表面は1.5–2 cm、広い面積は4–8 cm。
tbox/tplaneを使用。 - 照明されるすべてのマテリアルは
lit()を通過する必要があります。giPatchはonBeforeCompileを直接置き換え、lit()は元のパッチ(壁の変化wallPatch、布の逆光、風など)を後ろに連結します。 テクスチャがあるマテリアルにはalbedoを設定(テクスチャのavg)、反射光の色が正しくなります。 - 太陽の役割分担: 直接光は
DirectionalLight(強度はベイク設定のsun.irrと等しく)、反射光はファイルにベイク。環境光や半球光を追加してはいけません。 - 壁には中実の壁芯が必要で、壁芯の
shadowSideはFrontSideに設定。 これがないと、太陽光が壁の底や角から明るい点が漏れます(実際に発生しました。詳細はreferences/integration.mdを参照)。 - 露出は室内に合わせる。 室内はおおよそ室外の1/20:
exposure約4.5、窓外はext約0.3で暗くします。 - 反射はベイクの後に撮影する。
captureEnvはapplyBake/runBakeの後に実行し、プローブは部屋の中央に配置。 - 窓外に遠景がある場合、カメラの far 値は最も遠いオブジェクトよりも大きくなければなりません。 テンプレートでは400m(樹壁は100m、芝生は260mまで広がっています)。far が100しかない場合、遠景がクリップされた部分に白い水平線のフォグバンドが現れ、視点に追従します(実際に発生しました)。
- 太陽のシャドウカメラは窓外の樹冠をカバーする必要があります。 木陰が室内に落ちるように:テンプレートでは太陽を30m先に配置し、near 12、far 40。
実測(テンプレート、RTX 4090、Chrome headless、1280×800)
- シーン構築1.2秒、うちタオルの吊り下げ約0.65秒;10.7万トライアングル;ページ表示から画面出力まで約1.6秒。
- その場ベイク128 spp:61,407サンプルポイント、26ワーカー、6秒、gi.bin 743 KB。再ロード後、39メッシュに適用、無効0。
preview.jpg:部屋全体、机の側、窓、ライトのみ。preview-bake.jpg:左がフラットライト、右がベイク後。
さらに詳しく
references/workflow.md:各ステップの手順、行うべき決定、成果物とチェックポイント。references/integration.md:スキル間のインターフェース、注意点、遭遇した問題。references/checklist.md:検収チェックリストと数値の参考範囲。