threejs-rain-snow-and-wet-surfaces について
Three.jsで雨、雪、濡れた表面の表現を実装するスキルです。描画用パーティクルと受け面に蓄積する液体・雪を分離し、物理量と状態の所有者を明確にして各段階を連携させます。
主な機能
- 01気象状態の所有者と単位の定義
- 02解析的または再帰的な粒子運動の選択
- 03受け面積に基づく雨雪の積算
- 04気象と受け面状態の更新順序管理
- 05確定状態から雪や濡れを描画
- 06診断とリソース解放の検証
活用シーン
- 01カメラ移動に左右されない降雨の実装
- 02粒子数と独立した積雪量の計算
- 03表面への濡れ・波紋・飛沫の追加
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ linegel/ threejs-complete-set-of-skill --skill threejs-rain-snow-and-wet-surfacesインストール後、Claude Code で/threejs-rain-snow-and-wet-surfacesを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSEagents/openai.yamlexamples/physical-area-deposition.mjsreferences/precipitation-motion.mdreceiver-weathering.md詳細
雨、雪、濡れた表面
見た目を原因と結び付けます。1つの時刻ソースと風の場で空中の降水を制御し、各受け手につき1つの所有者が、堆積した雨または雪を積算します。融解と再凍結では、液体と雪の間で質量を等量移動させます。どちらも蓄積量を増やしません。視覚的な粒子数は天候をサンプリングするものであり、堆積質量を決めるものではありません。
Three.js r185 の WebGPURenderer、TSL、ストレージノード、ノードマテリアル、ノードポストスタックを使用します。コンピュートやストレージを確保する前に、レンダラーを初期化します。
await renderer.init();
if (renderer.backend.isWebGPUBackend !== true) {
throw new Error('This weather path requires the WebGPU backend.');
}
システム間で降水や受け手の状態を共有する場合は、単位、座標系、時間間隔、権限/バージョン、適用範囲、有効性、リセットの仕様を明記します。所有権が複数のスキルにまたがる場合は、$threejs-choose-skills を呼び出します。
構築手順
1. 所有者と単位を明確にする
次を明記します。
- 単調にサンプリングされる時刻ソースと、秒単位の更新間隔を1つずつ。
- ワールド座標系でメートル毎秒単位の風速場を1つ。その座標系、適用範囲、更新頻度、有効性も含めます。
- 相の判定、融解、蒸発がそれらに依存する場合は、ケルビン単位の温度と、明示した湿度の規約。
- 物理的な受け手の適用範囲に対する、
kg m^-2 s^-1単位の液体/氷の質量面積フラックスとしての降水強制。 - 液体または雪の蓄積量ごとに1つの受け手状態の所有者。
- HDR 表示、トーンマッピング、出力変換ごとに1つの所有者。
雲の見た目と、因果関係に基づく降水は別の分岐として扱います。見た目のみの雲は、アートディレクションの調整に利用できます。因果関係に基づく雲のソースは、質量フラックスまたは空中の蓄積量を、落下遅延/輸送モデルとともに公開します。雨は、後続の順序付けられたステージで、それを受け手まで輸送します。
原因と永続状態の所有者がそれぞれ1つに定まり、交換されるすべての量に単位と座標系があり、各プロデューサーが規定された有効期間内にサンプリングされると、この手順は完了です。
2. 状態を確保する前に移動方式を選ぶ
位置がシード、時刻、積分済みの風から厳密に求まる場合は、不変のシードと解析的な頂点移動を使用します。乱流、衝突、フィードバック、経路の履歴が次の状態に影響する場合は、GPU 常駐の再帰状態を使用します。時間変化する風を作成する場合、変位の積分を取得できるときに限り、解析的な方法を維持できます。現在の風速に経過時間全体を掛けると、風が変化したときにすべての粒子が跳ねるように移動してしまいます。
無限に広がる視覚的な天候には、アイデンティティ、スポーン位相、軌道が安定したワールド座標系でハッシュ化された、カメラ中心のセルをストリーミングします。局所的な天候には、意図的に境界を設定した、ワールド固定の有界ボリュームを使用します。衝突と蓄積には、視覚的なプールから独立した、ワールド上で安定した受け手セルを常に使用します。
解析的な移動と再帰的な移動の選択、コンピュート更新の実装、物理的な衝突の生成、降水処理の予算設定を行う際は、降水の移動を参照してください。
指定された各力または衝突が、厳密な解析項または再帰状態フィールドに対応し、カメラ移動テストで変化するのが表示されるセル集合だけであり、粒子の位相、衝突位置、受け手に蓄積された状態が変化しないと、この手順は完了です。
3. 堆積処理とビジュアルサンプリングを分離する
物理面積の求積を用いて、強度フラックスを積分します。
sum_i A_i = represented receiver area
deltaMass = deltaTime * sum_i(massFlux_i * A_i)
各 A_i には、平方メートル単位の物理的な受け取り面のヤコビアンが含まれます。水平面/発生源面のフラックスは、受け取り面に対する相対的な表面到達量に一度だけ変換します。このリファレンスでは、その投影と、すでに法線方向の到達フラックスとが区別されています。疎な衝突点が、すでに積分済みの移送量を表す場合は、その総量の質量と運動量を衝突点に分配し、合計が親の移送量と厳密に一度だけ一致するようにします。描画する軌跡/フレークの密度、スプライトのサイズ、ビジュアル LOD は、この計算の対象外にしてください。
この物理堆積分岐を実装する場合、または独立して監査する場合は、 物理面積堆積オラクルを参照するか、コピーしてください。これは変化する求積面積を受け付け、衝突点の分配を正規化せず、受け取り側の所有者が管理する総量質量台帳を検証します。これは CPU オラクルであり、実行時の状態管理主体ではありません。
同じ強制入力トレースのもとでビジュアル粒子数とビジュアル LOD を変更しても堆積質量と運動量が変わらず、受け取り側の更新間隔を変更しても時間積分が明示された数値許容誤差内に収まれば、このステップは完了です。
4. グリッド全体の更新順序を定める
次の因果順序を使用します。
latch time, wind, and precipitation forcing
-> advance analytic or recurrent airborne precipitation
-> resolve and bin impacts
-> publish deposition/impact transfer
-> integrate receiver liquid and snow state
-> commit receiver state
-> build render projection
後続の段階が先行する段階のグリッド全体の結果を消費する場合は、ソルバー、衝突/ビニング、スキャン/圧縮、間接引数、受け取り側の各パスを、順序付けされたディスパッチに分割します。ワークグループバリアが順序を保証するのは単一のワークグループ内です。グリッド全体の順序は、明示的なパスまたはキューの依存関係によって保証します。r185 の computeAsync() は、初期化/エンキューの簡便機能として扱い、GPU 完了フェンスとしては扱わないでください。定常フレームの状態は GPU 上に保持し、フレームのクリティカルな実行外でのみホストに読み戻します。
すべての読み出しについて、そのデータを生成したディスパッチまたは確定済みスナップショットが明示され、堆積の解決後に受け取り側で積分が行われ、固定の強制入力リプレイで、サポート対象の各更新間隔において同じ確定済みインベントリが生成されれば、このステップは完了です。
5. 確定済みの受け取り側状態を一つ投影する
雪の堆積、湿潤状態、水たまり、波紋の法線、飛沫、またはそれらのマテリアル応答を実装する場合は、受け取り側の風化を参照してください。
確定済みの受け取り側スナップショットから、すべての表面効果を構築します。
- 同じ高さフィールドから、雪による変位と雪の法線を導出します。
- オブジェクトの雪は安定したモデル空間でサンプリングし、変換後のワールド空間の支持法線を使って適用を制御します。
- 大雨の波紋法線を有効にする前に、初期の湿潤応答を適用します。
- 粗さ、吸収、波紋の適用可否、飛沫の強度、マスク診断には、同じ湿潤/水たまりマスクを使用します。
- ワールド空間の受け取り側法線に合わせて飛沫の向きを定め、下向き、支持されていない、または選択した可視性ポリシーのもとで隠れている候補を除外します。
雪の位置と雪の法線の診断結果が一致し、波紋を無効にしても湿潤状態が表示され、変換済みまたは遮蔽された受け取り側のテストで支持されたワールド空間の飛沫候補だけが許可されれば、このステップは完了です。
6. 表示して反証する
色、粗さ、法線、不透明度、変位には、MeshStandardNodeMaterial または MeshPhysicalNodeMaterial のスロットを使用します。1 つの
RenderPipeline を通して表示します。エンコードされたベースカラーのテクスチャには SRGBColorSpace のタグを付け、法線、粗さ、マスク、ノイズ、LUT、波紋、天候フィールドはデータとして扱います。単一のトーンマップ/出力変換の担当箇所に到達するまで、HDR バッファーはリニアのまま維持します。
リビジョンと経過時間の強制、モーション/セル、衝突、堆積質量、受け手側の項、雪の高さ/法線、濡れ具合/波紋、水しぶきの向き/可視性、データテクスチャの解釈、最終出力を確認する診断機能を公開します。指定したターゲットで、全画面および天候オン/オフのペアの CPU/GPU p50/p95、透明オーバードロー、フレームあたりのホットデータのバイト数、アクティブな衝突タイル数、最大ライブストレージを計測します。
以下の確認項目を最終ビューと診断ビューが満たし、診断レンダリングのバイパスを解除すると堆積した在庫を消去せずにベースラインへ戻り、降水を停止すると新たな入力だけが停止し、リサイズ/再構築で所有者を維持しつつ影響を受ける一時履歴だけをリセットし、破棄によって天候が所有するすべてのバッファー、テクスチャ、マテリアル、パスが解放されれば、この手順は完了です。
確認項目
| 確認項目 | 失敗時の症状と考えられる原因 |
|---|---|
| カメラを平行移動しても、降水の位相と衝突位置が維持される | セルの識別または衝突の範囲がカメラ相対になっています。 |
| 風が場全体を移動させず、今後のモーションの向きを変える | 現在の風に経過時間を掛けており、積分していません。 |
| 雨筋の長さが落下速度/露出に従い、流される向きが共有風に従う | スプライトのジオメトリまたはサーフェス側の分岐で、別のクロックや風を使用しています。 |
| 無制限の天候ではエミッターの継ぎ目がなく、局所的な天候では意図した端がある | 選択した視覚ドメインの契約が不完全です。 |
| 雪のシルエットとライティングが一緒に動く | 変位と法線が異なるフィールドから得られています。 |
| アニメーションするオブジェクトの表面に雪が付着し続ける | カバレッジが安定したモデル空間ではなく、ワールド空間でサンプリングされています。 |
| 強い雨による波紋が現れる前に、濡れたサーフェスの変化が起きる | 粗さが受け手側の濡れ具合ではなく、波紋マスクによって制御されています。 |
| 変換後も、水しぶきが受け手となる可視面に留まる | 候補法線または可視性がローカル空間/不安定な空間で評価されています。 |
| 高密度で繰り返し発生する天候に、雨粒ごとのオブジェクトループやホットバッファー全体のアップロードがない | 状態または表示処理が GPU 常駐の分岐から外れています。 |
| データフィールドの値が維持され、最終カラーに表示変換が 1 回だけ適用される | データテクスチャがカラーとしてデコードされているか、出力変換が二重に実行されています。 |
ルーティングの境界
範囲を限定した水域、屈折、コースティクス、Beer-Lambert 厚みには $threejs-water-optics を使用します。天候以外のパーティクルシステムには $threejs-particles-trails-and-effects を使用します。画面空間での接触履歴または消去履歴には $threejs-dynamic-surface-effects を使用します。シーン全体の HDR/ポスト処理の所有権には $threejs-image-pipeline を、大規模シーンのシャドウ割り当てには $threejs-scalable-real-time-shadows を使用します。このスキルは降水の移動と天候固有の受け手への投影を担当します。ルートによって選択された受け手の所有者が、持続する液体または雪の在庫を管理します。