threejs-dynamic-surface-effects について
threejs-dynamic-surface-effectsは、ビューポートに固定された外観履歴と合成を扱うThree.jsスキルです。永続的な表面効果を実装する開発者向けに、状態遷移、時間整合性のあるイベント更新、ping-pong GPUリソースを扱い、物理状態と画面表現を分離します。
主な機能
- 01履歴チャンネル、クロック、リソース所有権の定義
- 02状態遷移に応じた全体更新または疎更新
- 03減衰とポインターイベントの時間積分
- 04ping-pong StorageTextureによる履歴更新
- 05ぼかし、構造、屈折の合成とライフサイクル管理
活用シーン
- 01ポインターの軌跡に沿って蓄積する霜やタッチ効果の作成
- 02時間変化するスクリーンスペース表面履歴の実装
- 03疎更新、リセット、GPUリソース解放の検証
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ linegel/ threejs-complete-set-of-skill --skill threejs-dynamic-surface-effectsインストール後、Claude Code で/threejs-dynamic-surface-effectsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSEagents/openai.yamlreferences/ping-pong-accumulation.md詳細
状態遷移型の動的サーフェスエフェクト
ビューポートに固定された外観履歴とその合成を管理します。ワールド/オブジェクトの残留表現は $threejs-particles-trails-and-effects に、天候による蓄積は $threejs-rain-snow-and-wet-surfaces に、範囲が限定された水は $threejs-water-optics に、共有されるフレーム全体の出力判断は $threejs-image-pipeline に委ねます。
温度、相、読み込み、濡れ、接触、または天候が外観を左右する場合は、手順 1 の前に、以下を完了してこのローカルな引き継ぎを確定します。
- 物理量と単位、生成元の座標系/原点、変換と原点の世代、およびスクリーン UV への投影を明記します。
- ソースの時間区間、更新頻度、サンプル位相、不変の生成元/バージョン、およびレンダラー側のコンシューマーを明記します。
- サポート範囲/フィルター、妥当性、古さ、エラー、およびシグナル欠落時の方針を宣言します。
- GPU リソースの世代、生成パスと消費パス、および完了依存関係をひも付けます。
- 物理ソースは読み取り専用に保ち、スクリーン履歴には独自の外観バージョンを割り当てます。互換性のないクロック、原点、変換、投影、またはリソース世代の変更時にはリセットします。
フィードバックまたは追加のシステムオーナーが必要な場合は、$threejs-choose-skills を呼び出します。物理的な所有者が決定権を保持し、スクリーン UV 履歴は引き続きレンダラー所有の外観状態とします。
ローカル投影とリセットのルールについては、外部の外観シグナルを参照してください。
プロセス
1. 状態遷移と所有権を定義する
以下について、1 つの契約を記述します。
- 各履歴チャンネルと、その無次元の意味。
- スクリーン空間イベントの形状、タイムスタンプ、圧力/強度、および UV 原点。
- 減衰、堆積、拡散、変化なしなどの進化項。
- 状態クロック、中断/シークの方針、およびリセット依存関係。
- 履歴の単一ライター、合成コンシューマー、および最終出力の所有者。
- 外部の物理シグナルと、それとは分離して保持する装飾オーバーレイ。
タッチ/霜の履歴では、R に可視範囲を、A により滑らかな傾き/屈折応答を割り当てると便利です。G/B は未使用のままにするか、診断用として明示します。各チャンネルに方程式、ライター、単位領域、クロック、およびコンシューマーが 1 つずつ定義された時点で、この手順は完了です。
2. 更新トポロジーを選択する
視覚的なテーマではなく、状態遷移に基づいて選択します。
| 遷移 | 更新トポロジー |
|---|---|
| 減衰、拡散、または外力によってほとんどのテクセルが変化する | 全フィールドのピンポン計算 |
| 堆積がまばらで、影響を受けないテクセルが不変である | イベント境界またはダーティータイル |
| 状態がまばらで、かつ減衰する | タイムスタンプ付きタイルと、可視/フィルター対象サンプルごとの解析的な追いつき処理、または可視タイルのすべてでマテリアライズ |
| 多数のイベントが重なる | イベントをタイルにビニングし、リストの範囲を制限/圧縮するか、集約した堆積フィールドをラスター化 |
| 状態と入力が変化しない | アイドル:履歴を保持し、ディスパッチを行わない |
拡散には、全フィールドまたはハロー領域を拡張したアクティブドメインを使用します。オーバーラップのコストと拡散の安定性については、更新トポロジーを参照してください。影響を受けないテクセルが選択したモデルの要件どおりに進化し、アイドルフレームでは状態処理がスケジュールされない時点で、この手順は完了です。
3. 時間とイベントの統合を不変条件にする
同じクロック上の順序付けられた2つのサンプルからdtを導出します。サンプルが同じ場合は、経過時間をゼロとして扱います。前のサンプルがない場合、時間が逆行した場合、シークした場合、マッピングが無効な場合、または不連続が生じた場合は、宣言済みのフリーズ、リセット、解析的キャッチアップ、または有界サブステップのポリシーに従います。
タイムスタンプ付きポインターの動きを、履歴テクスチャのアスペクト比を使ったスイープカプセルとしてラスタライズします。減衰と飽和堆積を同時に積分し、ポインターを押し続けた場合とスイープジェスチャーの場合のどちらも、レンダーフレーム数に依存せず収束するようにします。イベント間隔は、圧力またはカバレッジの変動が宣言済みの誤差ゲートを超えた場合にのみ細分化します。
減衰、堆積、または拡散を実装する前に、dt補正履歴を確認してください。同じ時間指定入力で30、60、120 Hzのいずれでも同等の履歴が得られ、一時停止によって経過した時間の変化が暗黙に破棄されない状態になれば、このステップは完了です。
4. ピンポングラフを割り当てる
three/webgpuのWebGPURendererを使用し、await renderer.init()を呼び出して、この標準パスではrenderer.backend.isWebGPUBackend === trueを必須にします。WebGPUが利用できない場合の説明は$threejs-compatibility-fallbacksに振り分けます。再構築テストと量子化テストに合格する、実測済みの最小のサイズ/フォーマットで、レンダラー所有のStorageTexture履歴を2つ割り当てます。履歴、シーンカラー、ブラーの中間リソース、静的構造フィールドは、それぞれ別のリソースとして保持します。
グラフは次の順序にします。
immutable external appearance signals + timestamped UI events
-> write next history from previous history
-> publish/swap the completed history generation
single scene pass
-> optional separable blur at its owned reduced extent
-> static structure + current history composite
-> optional history-gated normal refraction
-> one RenderPipeline output transform
履歴の更新にはFn().compute(...)、storageTexture()、textureStore()を使用します。renderer.compute(...)でキューに登録します。r185のcomputeAsync()はGPU完了フェンスではありません。定常パスでは読み戻しを行わないようにします。出力ノード、診断経路、リソースのサイズ/フォーマット、または品質分岐が変わった場合は、レンダーグラフに変更を反映するか、再構築します。
テクスチャの割り当てやスワップの前に、リソースとr185の実行を確認してください。すべてのパスが確定済みの世代を読み取り、書き込み中のテクスチャをサンプリングするパスがなく、シーンが1回だけレンダリングされる状態になれば、このステップは完了です。
5. ブラー、構造、屈折を合成する
静的な結晶/ノイズフィールドは、起動時、またはサイズや品質が変わった場合に一度生成します。これらのデータにはNoColorSpaceを使用します。パスごとに設定した縮小解像度で分離可能なブラーを適用し、アルファが関与する場合はアルファを考慮した正規化を行います。TSLノードとしてコンポジットと屈折を構築し、RenderPipeline.outputNodeに入力します。
単一の出力変換を適用するまで、シーンと作業用バッファはリニア/HDRのままにします。スクリーン周期のユニフォームは周期として扱い、テクセルの寸法は実際のリソースから導出します。構造カバレッジと現在の履歴に基づいて屈折を制御し、法線のラップ方法とソース端の処理を定義して、Fresnelはリニア光で適用します。
いずれかの分岐が有効な場合は、コンポジットと屈折を確認してください。ブラーのサイズ、テクスチャドメイン、UV規約、屈折の範囲、出力変換がそれぞれ管理され、診断で確認できる状態になれば、このステップは完了です。
6. ライフサイクルを完結させる
リサイズ時のポリシーとして、2つの履歴をクリアする、再マッピングする、または深度/カメラを考慮して再投影する方法のいずれかを選びます。クロック、原点、変換、投影、リソース世代、表現、または品質に互換性のない変更があった場合は、リセットまたは再投影を行います。通常の連続的なソースバージョンの進行は、リセットせずサンプリングします。
アイドル時は永続状態を保持し、更新処理を停止します。再開時は、新しい入力を受け入れる前に宣言済みの時間ポリシーを適用します。破棄時またはデバイス損失時には、履歴の世代を無効化して、2つの履歴、ブラー/静的リソース、コンピュート/パイプラインノード、入力/リサイズのリスナーを解放します。次の描画の前に新しい世代を作成します。
リサイズ、リセット、破棄を確認してください。リサイズ、シーク、品質変更、アイドル/再開、破棄、デバイス損失のそれぞれについて、明示的な状態遷移とリソースの結果が定義されていれば、このステップは完了です。
7. 状態と表示を検証する
過去の履歴、堆積、次の履歴、変更タイル/アクティブテクセル、 シーンカラー、ブラーの各軸、静的フィールド、履歴前後のマスク、屈折オフセット、 屈折なしの最終出力、および最終出力を表示します。一時停止とステップ実行のコントロールを追加します。
イベント数、タイルリストの使用率、ディスパッチされたテクセル数、履歴と 中間データのバイト数、トラフィックの下限、ディスパッチ/描画の所要時間、およびフレーム全体の p50/p95 を測定します。状態の等価性テスト後に、アイドル時の処理を停止し、有効なスパースパスを選択し、その後、履歴/ブラーの範囲または精度を下げて拡張します。
リソースの計上および 診断と障害の兆候を参照してください。 入力を 30/60/120 Hz で計測しても一致すること、フル/スパース/アイドルの各遷移が選択どおりに動作すること、ピンポン世代が決してエイリアスしないこと、リサイズ/リセット/破棄のコントロールが正常に動作すること、物理入力が読み取り専用のままであること、フレームループで履歴の読み戻しがゼロであること、シーンが 1 回だけレンダリングされること、出力変換の担当が 1 つであること、そしてシーン全体が明示されたメモリ、トラフィック、時間の予算を満たすことをもって、このスキルは完了です。