scenario-blender-geometry-nodes について
プロシージャルシステムやシミュレーションを構築する、Agent向けのBlender Geometry Nodesスキルです。フィールドとドメインの計画、再利用可能なモディファイアーアセット、ジオメトリ計測、レンダー確認、シミュレーション検証を扱います。
主な機能
- 01フィールド、ドメイン、データフローを計画
- 02bx_gn.Builderでノードツリーを構築
- 03再利用可能なモディファイアー入力を公開
- 04評価後のジオメトリと属性を計測
- 05シミュレーションとレンダー結果を検証
活用シーン
- 01サーフェスへの散布システムを作成
- 02カーブ配列や成長表現を構築
- 03状態を保持するパーティクルシミュレーションを設定
- 04再利用可能なGeometry Nodesアセットをパッケージ
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ scenario-labs/ skills --skill scenario-blender-geometry-nodesインストール後、Claude Code で/scenario-blender-geometry-nodesを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/critique.mdexpert-notes.mdprocedures.mdsources.mdscripts/bx_gn.py詳細
Blender Geometry Nodes(プロシージャルシステムとシミュレーション)
Geometry Nodes を使ったエキスパートの作業では、ドメイン上で評価されるフィールドとして考え、システムを宣言的に保ち(データと指示は外部から受け取り)、アーティストがツリーを開かずにモディファイアーの入力から操作できるツールを提供します。エージェントにとっては、評価後のジオメトリから読み取った数値とレンダーを使ってすべてのツリーを検証することも意味します。ノードエディターの赤いリンクや警告は、明示的に要求しない限り Python からは見えないためです。ここに記載されている関連スキルが利用可能なスキルにない場合は、ユーザーにインストールを依頼してください(npx skills add scenario-labs/skills --skill <name>)。無人で作業する場合は、ツールスキーマに基づいて進め、不足している点を明示してください。
必須の背景知識: scenario-blender-expert(実行チャネル、レビューループ、5.2 API の変更)。 ヘアノードグループ(Interpolate、Clump、Curl、Hair Dynamics のグルーム):scenario-blender-hair。
基本方針(エキスパートとしての追加視点)
- フィールドはデータではなく、後で評価される問いです。 Thommes:フィールドは、それを使うノードによって、そのノードのドメインとジオメトリ上で評価されます。値は、名前が付けられるか、使用されるまで存在しません。結果として、[追加・検証済み] 位置と速度のような、連動する更新は同じ Capture Attribute でまとめてキャプチャする必要があります。そうしないと、2つ目の更新で1つ目の新しい値が読み取られます。
- ドメインが変わると補間され、すべての値はルールに基づいてブール値になります。 Erindale:float > 0 は true(ベクトルはゼロ以外の要素があれば true)となるため、細分化された頂点グループの選択範囲は広がります。Float to Integer または Compare と epsilon を使って判定してください。ジオメトリを生成し、その順序が設計の一部である場合を除き、インデックスによる選択ではなく、形質に基づく選択(position、normal、proximity、raycast)を優先してください(Blender Studio のマトリックス動画では、Index == 0 からスタックを駆動しています)。
- 履歴が重要な場合に限り、シミュレーションを使います。 Thommes:シミュレーションとは状態に適用されるルールであり、アニメーションとは時間の関数です。前のフレームに依存するものがなければ、Scene Time から駆動すれば、スクラブやサブフレームをそのまま利用できます。
- ループは最後の手段です。 Thommes:すべての要素に対して動作する組み込みノードは高速化構造を使用しますが、ループでは使用できません。For-each は、要素ごとに一度実行されるブラックボックスのジェネレーターに使います。フィールドはループの外側に、単一の値は内側に配置します。
- すべてオブジェクトローカルです。 Thommes:(0, 0, -1) のベクトルはオブジェクトとともに回転します。ワールド方向は、Self Object > Object Info > Invert Matrix > Transform Direction を通してください。
- ツリーではなく、ツールを作ります。 Thommes:シーンへの依存関係と調整可能な値はすべてグループ入力として公開し、再利用可能なツリー内でオブジェクトを直接参照してはいけません。また、ギズモは Group Input ソケットからのみ駆動し、逆変換可能な数式を通して、各 math ノードの最初の入力に接続してください。
- 5.2 の物理演算は宣言的です。 Thommes(BCON26):力、コライダー、拘束は、バンドルとクロージャとしてブラックボックスのソルバーに渡されます。まず外部からカスタマイズしてください(入力、バンドル、Custom Effector のクロージャ)。組み込みの拘束を編集する場合に限り、アセットをローカル化します。ステップごとのカスタム属性はすべて Extra Sim Attributes に列挙する必要があり、トポロジーが変化するシミュレーションでは、新しい要素を末尾に追加してください。
最初に確認すること
| 質問 | 計画が変わる理由 | 指定がない場合のデフォルト |
|---|---|---|
| 結果を使用するのは何ですか?シェーダー、別のモディファイアー、エクスポート、物理演算のどれですか? | 境界を越えるには名前付き属性が必要です。エクスポートではジオメトリの実体化が必要な場合があります | シェーダーが読み取るものには名前付き属性を使用し、インスタンスを維持する |
| 前のフレームに依存しますか? | シミュレーションゾーンでベイクするか、Scene Time 関数を使うかが変わります | 時間の関数 |
| 一度限りの作成手順ですか、それとも再利用可能なアセットですか? | 一度限りなら適用できます(Thommes のヘアノイズなど)が、アセットには適用しません | 再利用可能:入力、パネル、適切な最小値/最大値を公開する |
| 規模:要素数、ビューポートの負荷 | 実体化、ループ、シミュレーションにはコストがかかります。インスタンスは低コストです | インスタンス、フィールドを使用し、ループは使わない |
| 方向と地面にはワールド空間とオブジェクト空間のどちらを使いますか? | オブジェクトローカル座標には落とし穴があります | ワールドの上方向、ワールドの重力 |
ワークフロー
- データフローを計画します。 各値が属するコンポーネントとドメイン、各フィールドが評価される場所、適切なプリミティブを明確にします。まずは通常のフィールド、グループごとの合計には Accumulate Field、依存するパスを N 回実行するには repeat zone、各要素に対するブラックボックスジェネレーターには for-each、状態には simulation zone、動作の注入には closure、複数の名前付き値の受け渡しには bundle を使います。GATE:各フィールドをどのノードが評価するか、すべて説明できること。
bx_gn.Builderで構築します(ヘッドレスまたはライブで実行でき、冪等です。同じ名前のツリーはその場で再構築されます)。b.node(kind, prop=..., ins={...})は入力より先にプロパティを設定し、ソースをリンクして定数を割り当てます。b.zone(...)はゾーンをペアにして項目を追加します。b.join([...])はリストの順序を保ちます。GATE:b.done()が(ペアになったゾーン、作成されたすべてのリンク)を返すこと。- 入力を接続して設定します。
G.attach(obj, tree, inputs={...})またはG.set_inputs(md, {...})を使います。"attr:NAME"を指定すると、フィールド入力が属性または頂点グループに切り替わります。GATE:G.check(md)["ok"]であること、アセットにhard_refsがないこと。 - 計測します。
G.stats(obj)(カウント、ドメインごとの属性、インスタンスを含むワールドバウンディングボックス)、G.attribute、G.instance_transforms、G.positionsを使います。次に、堅牢性を確認する 2 つのテストを行います。オブジェクトを 90 度回転する(ワールド空間の効果は方向を維持します)ことと、入力解像度を 2 倍にすること(特性による選択はスケールし、インデックスによる選択はジャンプします)。GATE:数値が解析上の予想と一致すること。 - 見た目を確認します。
G.snapshot(objs, path, views=..., frames=...)は、マテリアルの色と影を含む現在のシーン状態をレンダリングします(浮遊するインスタンスも表示されます)。実体化したメッシュにはbx_review.reviewを使います。すべてのシートを開きます。GATE:references/critique.mdのビジュアル項目に合格すること。 - シミュレーションを実行します。
G.step(range(...))ですべてのフレームを順番に進めるか、ランダムアクセスにはG.bake(obj)を使います。境界、状態の単調性、カウント、NaN がないことを確認します。GATE:後のフレームに直接ジャンプした場合、ベイク後にのみステップ実行の結果と一致すること。 - パッケージ化します(アセットの場合)。入力をデフォルト値、最小値/最大値、サブタイプとともにパネルにまとめます。
tree.is_modifier = True; tree.asset_mark()を設定し、別のオブジェクトに適用します(Thommes の Suzanne テスト)。GATE:ツリーを編集せずに 2 つ目のオブジェクトでも動作すること。
scripts/bx_gn.py にあるレシピは、テストおよびレンダリング済みです。scatter_tree(密度 x マスク、ワールド空間の傾斜制限、直立または整列、オブジェクトやコレクションから選択)、curve_array_tree(接線に整列した配列、交互のひねりでチェーンを作成)、growth_tree(repeat-zone による押し出し)、particle_drop_tree(放出、ワールド重力、地面での跳ね返りを伴う simulation zone)があります。入力が要件を満たす場合は、同梱の Essentials アセット(Scatter on Surface、Array、Instance on Elements、Randomize Transforms)を優先してください。ワールド空間のルール、マスク、カスタム属性が必要な場合は、独自に構築してください。
数値
| 値 | 対象 | 出典 |
|---|---|---|
| Melt シミュレーション:周囲温度 300 K、発生源 2000 K、フレームあたりの加熱 0.05、冷却 0.01 | 各ステップの Mix 係数。累積するため小さめです | Thommes BCON23 |
| Blur Attribute のウェイト 0.5、スムーズ化 5 回、melt マスク 500~2000 K | 熱拡散と軟化 | Thommes BCON23 |
| フレームあたり 0.01 で -Z 方向に垂らす。法線の Mix 0.1(0.5 は「パンを焼いているように見える」) | 各ステップのオフセット | Thommes BCON23 |
| 破断しきい値 1 は静止長より長くなるとすぐに破断します(敏感すぎます)。補強 10、基本ランダム値 1~1.1、Voronoi モード | エッジ長比 | Thommes BCON26 |
| 縫合ランプ:累積 Delta Time の 1 秒間で、静止長の係数を 1 から 0 にします | 急なスナップを防止 | Thommes BCON26 |
| 破断部分の糸:約 2 cm、各 3 点 | パフォーマンス上限 | Thommes BCON26 |
| 布アセットのデフォルト:Substeps 5、Constraint Steps 15、Collision Radius 0.01、Tearing Threshold 1.2 | 5.2.1 アセットから読み取り | digest [verified] |
| Gizmo の位置 = サイズ x 0.5(中央揃えのグリッドの場合)。SECOND 入力のランダム係数は 0.2~1 | ドラッグを密着させます | Thommes BCON24 |
| スタック:ボックスの原点は底面。ランダムスケールは XY 1~1.5、Z 0.05~0.3 | Accumulate Field Trailing | Matrix video |
| 領域の平坦化:島の最小面数 5。近接範囲の減衰 0~0.2 m、Smoother Step。Volume to Mesh のしきい値は約 0.5 | Erindale の演習 | Erindale |
| Realize Instances:Realize All をオフ、Depth 1 | 階層を 1 レベル平坦化します | Thommes BCON24 |
品質ゲート
測定可能(コード):
G.check(md):ok(無効なリンクなし、ERROR 警告なし、ゾーンのペアが一致)、アセットのhard_refsは空で、追加した Warning ノードは想定どおりに報告されます。- 数が想定と一致します:散布数は密度 x マスク x 対象領域の約 12 パーセント以内 [verified test]。カーブ配列数 = floor(length / spacing)。反復による面の増加数 = F0 + sides x selected x iterations。
- 属性が正しいドメインと型で存在し、値が範囲内です(
G.attribute)。 - 回転プローブと解像度プローブ(ステップ 4)。
- シミュレーション:フレームごとの数、境界(地面より下に何もないこと)、追加時にプレフィックスが安定した ID、単調であるべきエネルギーまたは状態、ベイク結果とステップ実行結果が一致すること。
- 高負荷のツリーには
G.time_eval(obj)を使用し、その中の repeat または for-each ゾーンにフラグを付けます。
ビジュアル(G.snapshot、bx_review):散布密度が自然に見え、浮いたり沈んだりするものがありません。配列が反転せずカーブに沿っています。成長部分の根元に自己交差がありません。シミュレーションの帯には動きの後に静止する様子が表示されます。シェーダー駆動の属性はレンダー解像度で確認します。Gizmo の操作感は GUI でのみ確認します。
よくある間違い
| 間違い | 症状 | 修正 |
|---|---|---|
ツリーをまたいで tree.links.new を使う | None が返され、何もリンクされず、エラーも出ません | Builder.link を使うと例外が発生します。ツリー切り替え後にバインド済みの links.new を再利用しないでください |
md.properties.inputs.<id>.value だけを設定する | 結果が変わりません | obj.update_tag()(または G.set_inputs)を実行します |
| For-Each ゾーン内で暗黙の ID を持つ Random Value を使う | リンクが赤くなり、出力が警告なしで誤った値になります。md.node_warnings は空です | ゾーンの Index を ID に接続します。G.check に invalid_links が表示されます |
| 2 つの Random Value ノードで同じ Seed を使う | スケールと回転が連動して変化します(相関係数 1.0[検証済み]) | Seed をずらします(seed + k) |
| Simulation Input から Output への状態の配線がない | 値が各フレームでリセットされます | すべての状態項目を経由するように配線します |
| Cloth または Hair Dynamics 内でカスタム属性を使う | 各ステップでリセットされ、警告も出ません | Extra Sim Attributes に追加します |
| アセット内でコントローラーオブジェクトを直接参照する | 一度は動作しますが、再利用すると動作しなくなります | Group Input に Object ソケットを追加します |
| 2 つのノードで連動するフィールドを更新する | すでに移動した位置から速度が計算されます | 両方に 1 つの Capture Attribute を使います |
| Join の順序がリンク順と同じだと思い込む | 新しい要素が先頭に挿入され、ソルバーまたは ID が壊れます | b.join([state, new]) を使います |
| ローカル方向をワールド方向として使う | オブジェクトとともにエフェクトが回転します | Self Object の行列変換を使います |
| 自動生成されたシグネチャに頼る | ERROR "Closure does not have output" が発生します | 両方の項目リストを作成し、名前を同じにします |
Blender 5.2 に関する注意事項
- モディファイアーの入力:
md.properties.inputs.<Socket_N>.value(従来のmd["Socket_N"]は TypeError が発生します)、 続けてobj.update_tag()を呼び出します。 - メニューは入力ソケットです。Transform Geometry の
Mode= 'Matrix'、Resample Curve のMode、Custom Force のMode、Custom Effector のStage(メニューはSocket_1。文字列入力も Stage という名前で、Socket_2です)。 - Mix の
node.inputs["A"]は 5.2.1 では利用可能なソケットを返します。重複した有効名(Cloth の 2 つのGravity) では、引き続き識別子が必要です。bx_gn.sockは識別子がないとエラーになります。 - Join Geometry では、最後に作成されたリンクが先頭に置かれます[確認済み]。
- 評価済みの
obj.bound_boxはインスタンスを無視します。インスタンスのポイントクラウドのposition属性は ゼロを返すため、代わりにinstance_transformを使用してください[確認済み]。ヘッドレスではmd.execution_timeは 0.0 のままです。 - シミュレーション:最初のフレームですでにゾーン本体が実行されます。キャッシュを飛び越えると 1 ステップ計算されます。
simulation_nodes_cache_calculate_to_frameはヘッドレスで PASS_THROUGH を返し、何も計算しません。simulation_nodes_cache_bakeは動作します(パック済み)[確認済み]。 - リスト(Field to List、Get List Item)、バンドル、クロージャ、
GeometryNodeXPBDSolverが存在します。モーダルノードツールはありません(実験的ビルドのみ)。 - 同梱アセット:
<DATAFILES>/assets/nodes/geometry_nodes_essentials.blend、geometry_nodes_dynamics_assets.blend、procedural_hair_node_assets.blend(G.append_group(name, library))。
参考資料
references/expert-notes.md:Thommes、Erindale、Johnny Matthews の原則とタイムスタンプ。システムまたはアセットの設計時に読み込んでください。references/procedures.md:検証済みコード。raw-bpy の手順 A〜H (属性パイプライン、浮動小数点シミュレーション、リピート展開、for-each、クロージャ、行列の積み重ね、ギズモ、 クロス)と bx_gn のレシピおよび物理テストが含まれます。ツリーを書く前に読み込んでください。references/critique.md:ツリー、アセット、シミュレーションを評価するための基準。各ゲートで読み込んでください。references/sources.md:8 本のソース動画、それぞれの用途、おすすめのタイムスタンプ。scripts/bx_gn.py:ビルダー、モディファイアー、評価、シミュレーション、スナップショットのヘルパーとレシピ(docstring に注意点が記載されています)。