2024年11月6日(現地時間)Blender開発ブログで共有されたジオメトリノードワークショップの紹介です。
Blenderカンファレンスの後、Geometry Nodesチーム(以下開発チーム)が再び集まり、多くのデザイントピックについての話し合いが行われました。
今回のワークショップには、Lukas Tönne氏、Hans Goudey氏、Simon Thommes氏(午後~)、Jacques Lucke氏が参加。Dalai Felinto氏がワークショップの開始を手伝い、Falk David氏も時々参加したとのことです。
今回の主な焦点は、ジオメトリノードにおける物理、特にヘアダイナミクスのサポートを改善することとのことですが、それに加えて、その他多くのトピックが議論されています。
これらの議論の内容から、ジオメトリノードの今後の新機能についての情報を見ることができます。
以下その内容となります。
前回のジオメトリーノードワークショップの内容
前回のワークショップは5ヶ月前に行わました。以下は、そこで議論したトピックについての簡単な最新情報です。省略されたトピックにはニュースはありません。
- ギズモ(Gizmos): ギズモは、Blender 4.3リリースに含まれています。この次のステップは、Transform GeometryやGridノードのようないくつかのビルトインノードにギズモを追加することです。
- ベイク(Baking): ベイクをパックできるようになりました。この機能もBlender 4.3リリースに含まれています。次のステップは、シーン内で複数のベイクを扱うためのより高いレベルのツールを提供することです。
- ノードのソケット名の変更 : Ctrl+クリックによるソケット名の変更が、いくつかのノードで機能するようになりました(Bake、Simulation、Capture Attributeなど)。ダブルクリックや右揃えのラベルで機能させるのは、技術的に難しい点があります。
- Tools for Node Tree UX: ビルトインノードがソケットセパレーターをサポートしました(For-Eachゾーンで使用)。いずれノードグループにもサポートが追加される予定です。ビューアノードが自動的に位置を変更するようになりました。
- アセットの埋め込み: 動作をテストするためにプロトタイプが作られました。技術的な問題をどのように解決するかについては合意しましたが、UIについてはまだ不明な点があります(例えば、リンクや追加以外の新しい「インポート方法」としてどのようにユーザーに提示するかなど)。
- メニューソケット: 無効なリンクがあった場合のエラー処理が改善され、何が間違っているのかについて、より多くの情報をユーザーに提供できるようになりました。これはメニューソケットだけでなく、無効な型の変換のような他の無効なリンクにも適用されます。
- ソケットの形状: 誰もがトレードオフの関係に納得できるデザインが発見され、プロトタイプが作成されました。その作業はまだ続いています。
- グリースペンシル: Blender4.3からジオメトリノードで、グリースペンシルのデータを扱えるようになりました。
- For-Each ゾーン(For-Each Zones) : 4.3 には新しい For-Each Element ゾーンが追加されました。別の種類の For-Each ゾーンに関する作業が進行中です。
これらの最新機能の多くはBlender4.3に含まれています。
詳細は以下の記事をご覧ください。
物理へのアプローチ
ジオメトリノードで物理にどのようにアプローチするかを設計する際には、さまざまな視点を考慮する必要があります。今回は以下に焦点があてられました。
- 高レベルのノードグループアセットを使用して、例えばヘアシミュレーションをセットアップする。
- 特殊なエフェクトのためのソルバーの構築やカスタマイズ。
- モディファイアのみのワークフロー。
- ノードとモディファイアのインターフェイスを抽象化する高レベルのアドオン。
開発チームはまず、複数のジオメトリ操作を連鎖させる場合と物理シミュレーションをセットアップする場合では、考え方にかなり根本的な違いがあることを明確にしました。
その違いとは、シミュレーションを作成するときには、まず、望ましい動作(フォース、エミッター、コライダーなど)について考えるのであって、ジオメトリが実際に処理される順序についてはあまり考えないということです。実際、大半のユーザーは、特定のジオメトリ操作を気にすることなく、ビヘイビアだけを気にすればよいはずです。
そのため開発チームは、「望ましい動作の記述と実際の動作の実装」を分離するための良い方法を提供することを考えているとのことです。これは宣言的(declarative)アプローチと呼ばれ、潜在的に非常に複雑な評価システムを高レベルで制御できるようになり、希望するすべてのビヘイビアを動作させることができます。
この宣言的アプローチは、ブラシエンジンや スキャッタリングシステムの構築など、物理学以外のことにも非常に役立つとされています。
この分離を実現するために、バンドル(Bundles)とクロージャ(Closures)という2つの新しいソケットタイプが導入される予定です。
バンドル
バンドル(Bundles)とは、複数の値を一つのソケットにまとめることができるコンテナで、異なる型の値を1つのバンドルに入れることができます。
すでに開発中のパッチが利用可能です。
バンドルは必要なリンクの数を減らすのに非常に便利な機能です。現在のところ、「バンドル」が、さまざまな種類のシミュレーション動作のための統一インターフェースを作成するためにどのように使用できるかに焦点が当てられているとのことです。
各動作は、ソルバーが何をすべきかを理解するために必要な情報を含むバンドルになる予定です。
クロージャ
クロージャ(Closures)ソケットは、ノードグループ全体を含む任意の関数を渡すことができます。
例えば、ノードグループを入力として別のグループに渡すことができ、そのグループによってノードグループが評価されます。
これはBlenderのノードシステムにおいて全く新しいパラダイムで、関数をデータとして渡すという概念に慣れていなければ、理解するのは簡単ではありません。しかし、これは非常に強力で、より柔軟でユーザーフレンドリーな高レベルのノードグループを構築することができます。
プログラミングでは、「Closure」という用語は、データとして渡すことができ、変数が作成された場所から変数をキャプチャすることができる関数を指します。これに代わる良い名前はまだ見つかっていません。
クロージャを作成するには、新しいクロージャゾーンを使います。これは、小さなローカルノードグループを作成し、それを受け渡すようなものです。
他のゾーンタイプと同様に外部からクロージャーにデータを渡す機能が必要なので、既存のノードグループを使うだけではうまくいきません。また、ノードツリー全体を1つのグループで構築し、すべてを一度に見ることができるのも良い点とされています。
位置ベースのダイナミクス
バンドルとクロージャを使った宣言的アプローチは、あらゆる物理シミュレーションに有効です。開発チームは、ユーザーが独自のソルバーを構築できるようにすることに加え、ヘアシミュレーションをジオメトリノードに直接統合したいと考えています。
ヘアシミュレーションは、位置ベースのダイナミクス(PBD/XPBD)ソルバーを中心に設計されています。このソルバーは、ソフトボディシミュレーション、布、毛髪、粒状材料などに適用されています。
PBD法はリアルタイムゲーム物理学によく使われ、実装が比較的簡単です。また、現在ヘアダイナミクスに使用されているリニア化された速度ベースの布ソルバーよりも、速度と精度の点で優れています。このトピックに関する学習リソースや科学論文はたくさんあるので興味がある方は調べてみてください。例えば、こちらの概要とビデオチュートリアルシリーズが特に役に立ったとのことです。
開発チームは、可能な限り多くの部分を汎用ジオメトリノードを使用して実装する予定ですが、衝突検出やコンストレイントのグループ化のような一部の部分は、パフォーマンス上の理由から新しい組み込みノードが必要になる可能性があります。これについては、その時になって判断するとのことです。
リスト
今回のプロジェクトでは、ソルバーに渡される動作のリストを管理したり、衝突検出後の接触点を処理したりするために、さまざまな場所でリストが必要になると思われます。
リストは以前のワークショップでも話題になったものですが、これまでになかったような新しい情報はあまりありません。基本的なアイデアは、独立したリストをサポートし、それらに対してさまざまな操作を行うことです。
生成されたヘアを複数のガイドヘアストランドにマッピングする必要があるため、リストはヘアにとって特に重要です。現在のところ、このマッピングを保存する良い方法がないので、ガイドを使うワークフロー、特にシミュレーションのためのワークフローは、信頼性がかなり低くなっています。
リストをジオメトリノードに導入する主な障害は、ソケット形状の議論です。
ソケット形状
現在、ジオメトリノードでは、異なる種類の値を表すために3つの異なるソケット形状を使用しています。円は単一の値を意味し、ダイヤモンドはフィールドを意味し、点のついたダイヤモンドは単一の値を参照しますが、フィールドになることもあります。
これまではそれでうまく機能していましたが、ボリュームグリッドやリストの導入の際にはこれが複雑となります。問題は、ソケット形状だけではすべての情報を表示できないため、表示しない情報を決める必要があることです。
前回のワークショップでこの議論が行われましたが、新しいタイプ(フィールド、リスト、グリッド、画像など)を取得した場合にソケット形状をどのように扱うかについて結論には至りませんでした。
過去数ヶ月間、このトピックに関するデザイン作業が進められ、シンプルなプロトタイプも作成されました。現時点で解決策のトレードオフに少なくとも納得しているため、このトピックを進めることができるとのことです。
これが解決されると、ボリュームグリッドやリストをリリース可能な状態にするのが簡単になります。
For Each Geometry Zone
Blender 4.3には「For Each Element zone」が含まれています。これは非常に便利ですが、他にも役立つ「for-each」のゾーンがあります。その 1 つが「For Each Geometry」ゾーンです。これは以前のワークショップで「For Each Unique Instance」と呼ばれていたものです。
その目的は、インスタンス階層を含むジオメトリセット内の各「実際の」ジオメトリを反復処理することです。多くの組み込み(ビルトイン)ノードは、すでに内部的にこれを行っています。例えば、サブディビジョンサーフェス(Subdivision Surface)ノードは、インスタンス内のものを含むすべてのメッシュにその効果を適用しています。
新しい「For Each Geometry」ゾーンを追加することで、すべての組み込みノードとカスタムノードグループに同じ機能を追加することができます。 これは「For Each Element zone」の「Instances」モードとはかなり異なります。処理されるジオメトリに同じメッシュの多数のインスタンスが含まれている場合、既存のゾーンは各メッシュごとに個別に実行されますが、この新しいゾーンはメッシュが 1 つしかないため、一度しか実行されません。
すでに#123021で設計作業が行われています。
モーダルノードツール
1年前のモーダル(Modal)ノードツールの全体的なデザインを再確認しました。それ以来、現在Blenderには2種類のモーダルオペレーターがあることが分かっています。
- 初期状態に基づくオペレーター(例:ベベル)。これらには再実行パネルがあります。
- 各モーダルステップで前の状態を使用する履歴依存のオペレーター(例:ブラシ)これらには再実行パネルがありません。
どちらの種類のオペレータもノードで作成できます。ただし、これまでにモーダルノードツールについての議論は、主に2番目のタイプについてでした。最初のタイプの多くのユースケースは、ほとんどの場合、非モーダルオペレーターの入力値を制御するために使用されるため、おそらくギズモまたはギズモのようなシステムで解決できると考えられています。
また、すべてのノードツールが最終的には単一のオペレーター geometry.execute_node_group
に過ぎないという事実が原因で引き起こされる問題もあります。これは、解決不可能なものではなく、例えば、ユーザーはが他のキーマップと同様にこのキーマップをオーバーライドできることで解決することができます。通常、モーダルオペレーターとキーマップの間にはマッピングがありますが、前述の理由のように単一の操作であるためうまく機能しません。代替案として、オペレーターだけでなくユーザーの設定で特定のアセットにキーマップをアタッチするのもひとつの解決策です。
各ノードツールに対して個別のオペレーターを登録することも可能ですが、それには固有の問題が伴います。例えば、特定のアセット データ ブロックをオペレーター名で参照する方法が導入されると、オペレーター名の競合も簡単に発生する可能性があります。
フィールドコンテキストゾーン
新しい「フィールドコンテキストゾーン(Field Context Zone)」についての議論が開始されました。全体的なデザインは非常に未完成であり、周囲の多くの質問に対する具体的な答えはまだありません。全体的なアイデアは、フィールド評価コンテキスト(field evaluation context)へのアクセスをより明示的にすることとされています。
例えば、ジオメトリで評価されるフィールドの場合、新しいゾーンは入力としてコンテキストジオメトリを持ち、そのジオメトリに依存するフィールドを出力します。これにより、以前は非常に複雑だったフィールドの構築の新しい道が開かれます。
このゾーンは、ノードのデザインにおける冗長性も削減することができます。例えば、「Sample Index」と「Evaluate at Index」のようなノードは、一方が入力としてジオメトリを持ち、もう一方が持たないことを除いて同じです。このゾーンの目標は、「Evaluate at Index」ノードを「Sample Index」ノードから構築できるようにすることです。
追加のモディファイア評価出力
ジオメトリノードの制限の一つとして、次のモディファイアに渡されるジオメトリのみしか出力できないことがあります。別のジオメトリや単一の値などのデータを出力できると非常に便利な場合があります。これらの値は、オブジェクトの「評価された状態(evaluated state)」の一部となり、他のオブジェクトがノードやドライバーを使用して参照できるようになります。
これにより、ジオメトリノードから一連のベクトルを出力し、それをアーマチュアをの駆動に使用したりといったことが可能となります。さらに、次のモディファイアに渡される値のバンドルを出力することも可能です。この方法により、モディファイア間で渡されるジオメトリにすべての情報をエンコードしなければならないという制限なしに、よりリッチなモディファイアスタックを構築できるようになります。
また、オブジェクトからフィールドやクロージャを出力することも可能になります(一部のデータの存続期間よる制限があるかもしれませんが)。これにより、他のジオメトリノードのセットアップで理解できる動作を組み込む、さまざまなエフェクターオブジェクトを構築できるようになります。これは既存のフォースオブジェクトタイプの一般化と考えることもできるとのことです。
内部データソケット
場合によっては、完全に公開したくないデータを渡す機能を追加したいことがあります。良い例は、最近傍点を見つけるためのアルゴリズムやレイキャストの実行を必要とするアルゴリズムを高速化するためのKDツリーやBVHツリーです。これらのデータ構造には明確なAPIがありますが、最適化はファイルを破壊することが必要になるかもしれないため、実装の詳細を公開すると将来の最適化が非常に難しくなる可能性があります。
内部データの種類ごとに新しいソケットタイプを追加するのた有益ではないと考えられており、これまでのところ、さまざまな種類の内部データを渡すために単一のタイプ(単一の色)を追加するだけで十分だと考えられています。
過去に持ち上がったユースケースのひとつは、「Bake Reference」ソケットで、これによりBakeからImport Bakeノードにデータを渡すことができます(これが導入された場合)。Import Bakeノードの問題点は、ディスクからのベイクとパックされたベイクの両方を読み取る必要があることです。したがって、ファイルパス入力を与えるだけでは機能しません。ファイルからの読み取りはもちろん可能ですが、パックされたベイクのための解決策も必要となります。
グループ入力のデフォルト値
ノードグループのすべての入力にはデフォルト値があります。一部のタイプでは、現在デフォルトがハードコードされています(例:空のジオメトリ)。他のタイプはサイドバーで手動で選択でき、いくつかのソケットタイプはより複雑な入力をサポートしています。例えば、ベクターソケットはデフォルトで位置フィールドにすることができます。ただし、現在可能なデフォルトのセットはハードコードされています。このトピックの目標は、デフォルトのシステムを一般化して制限を取り除くことです。
全体のアイデアは、ノードグループのすべての入力に対して入力ソケットを持つ新しい「Group Defaults」ノードを持つことです。どの入力のデフォルト値も、以下のモックアップのようにノードに値を接続することで指定されます。 一部のデフォルト値を他の入力値に依存させることも可能ですが、それによってどれだけの複雑さが増すかはまだ明確ではないため、これは、後で行われる可能性があります。
扱いにくい点は、まだデフォルトが設定されていないソケットにデフォルト値を追加すると、これを使用するすべてのグループノードの値を上書きする可能性があることです。これはすでにある問題の逆のようなもので、グループ入力のデフォルト値を変更してもグループノードにまったく伝播しないという問題があります。問題は、値がすでに変更されたかどうかわからないことで、ノードグループが別のファイルからリンクされている場合はさらに厄介になります。
コンテキスト入力
このトピックの目標は、次の問題を解決することです:
- グローバルな入力値を取得するためのコントロールノードグループの必要性を取り除きたい (example)。一部の設定では便利ですが、再利用可能なノードシステムを構築する際にはあまりうまく機能しません。
- ヘアシステムのサーフェスジオメトリを適切な方法で関連するヘアノードに渡す良い方法がない。
- マウス位置(Mouse Position)、アクティブカメラ(Active Camera)、シーン時間(Scene Time)のような既存のコンテキスト入力ノードをオーバーライドする方法がない。
- パフォーマンス対クオリティのトレードオフをコントロールするために使用される 「Is Viewport 」ノードに代わる、より柔軟な方法が必要。「Is Viewport」ノードのより柔軟な代替品が必要です。これはパフォーマンスと品質のトレードオフを制御するために使用されます。レンダリング中かどうかに基づいてこの決定を下すだけでは十分ではありません。編集モードのときはノードグループの 「高速(fast)」モードを使い、そうでないときは「高品質(high quality)」モードを使う必要があります。
これらの問題に共通しているのは、ネストされたノードグループに情報を渡したいのに、中間リンクを設定する必要がないことです。それでも、どの中間レベルでも、これらの入力をすべて上書きできるようにしたいと考えられています。
すでに多くの既存のコンテキスト入力ノード(「Scene Time 」や 「Mouse Position 」など)がありますが、さらに、カスタム入力用の「コンテキスト入力」ノードの追加が計画されています。コンテキストノードが(ネストされた)ノードグループで使用されると、そのノードグループの入力が自動的に作成されます。より高いレベルのグループノードは、その入力に特定の値を渡すか、接続しないかを決めることができます。接続しない場合、コンテキスト入力はさらに上位に伝搬されます。
コンテキストの値がどのノードからも提供されていない場合は、Geometry Nodesモディファイアまで伝搬され、そこで再びユーザーが指定することができます。そうでない場合は、オブジェクトやシーンのカスタムプロパティから値を読み取ることができます。
この機能の作業中のプルリクエストがあります。
モディファイア入力
モディファイアのグループ入力にさらに多くの機能を追加することが計画されています。目標は、次の通りです:
- コンテキスト入力については、特定の入力を提供すべきかどうかを決定する機能が必要です。
- ジオメトリ入力では、オブジェクト入力とコレクション入力のどちらを使うか、また(Object Infoノードのように)元の空間を使うか相対空間を使うかを選択できるようにしたい。
これらの選択肢をすべてモディファイアに入れ、常に見えるようにすることは、UIの観点から問題があります。現在でも、単一値入力と属性入力を切り替えるボタンは、多くの場合必要ではなく、乱雑になります。
右クリックメニューや管理パネルにオプションを置いたり、一時的にすべての追加設定を表示することができる 「edit 」ボタンをモディファイアに置いたりすることで、どのように機能するかを検討した結果、
今のところ、最初のうちは多少発見しにくくても、右クリックメニューを使う方法がベストということになっています。
動的ソケット数のバンドル
バンドルについてさらに掘り下げていくと、バンドルは2022年に議論した、もう一つの長年の制限である動的なソケットカウント(dynamic socket counts)に対しても良い解決策があることが判明しました。
それ以来、動的ソケット数のサポートが向上し、現在ではすべてのゾーン、「Capture Attribute」および「Bake」などの複数のビルトインノードでサポートされています。不足しているのは、動的な入出力数を持つノードグループの構築のサポートです。
ノードグループの入力バンドルには、拡張可能なソケットとしてタグを付けることができます。そうすれば、外部から複数の値を渡すことができ、それがグループ内のバンドルになります。グループからそのバンドルを出力するときは、すべての値は再び分離されます。
グループ内部では、ノードがバンドル内の全ての要素を処理することになります。ビルトイン ノードは、それを自動的に行うことができます。例えば、Capture Attribute ノードがバンドル入力を持つとき、含まれる各フィールドを再帰的にキャプチャし、キャプチャされた匿名属性フィールドに置き換えることができます。似たようなことは、すでに動的なソケット数を持つ他のノードでもできます。
コメント