BlenderのGeometry node(ジオメトリーノード)の話です。
ジオメトリーノードの学習において、いくつか鬼門があると思っているんですが
- インスタンスの扱い
- Fieldの使い方
- Raycastノードの使い方
- Geometry Proximityノードの使い方
- Sample Index, Sample Nearestノードの使い方
- Matrixの理解
- Mathノードの理解
- …etc
今回この中のSample Index, Sample Nearestノードの使い方について、できればわかりやすく基礎的な使い方を解説するのと、インデックスなどの値を転送できるようにまとめてみたいと思います。
この記事は、BlenderのSample Index, Sample Nearestノードの使い方について解説した中級者向けの記事です。
難易度
Sample Index, Sample Nearestノードの何が難しいかって、他の多くのノードと違って、ジオメトリノードの中で、複数のジオメトリを扱う必要があることだと思います。
右図がイメージ図なんですけど、二つジオメトリを出して、一方のインデックスや位置などの属性値を、もう一方のジオメトリに移したり、その値を利用するような使い方が多いと思います。

旧バージョンだと、Transfer Attribute(属性転送)ノードっていうのがあって、その名前のごとく別のジオメトリに情報や属性値を転送できていたみたいです。自分はあんまりそのバージョンは使ったことがないので詳しくはわかりませんが、このノードがなくなり、その変わりとしてSample Index, Sample Nearestノードで属性値を転送するっていうのが現バージョンのやり方になっています。
そもそもなぜ属性値を転送したいのか?
近くにある物体との関係性
ある程度ジオメトリーノードでいろいろ作っていると、ある床面を動いてる物体を作りたい、とか、他の物体との関係性で動きを作りたくなってくるときが出てきます。
そのときに他の物体、例えば床のNormal(法線)情報が使いたいとか、近くの物体の位置を知りたいという動機が出てきます。物を避けたり、床がぼこぼこしてても動きの方向を合わせたりできます。
ジオメトリーノードで難しそうなことやろうとすると、いろいろな情報を使えた方がいいので、周囲のジオメトリの属性値を把握したり転送するっていう技術は必須になってくるかなと思います。
インスタンスに分けたい
最近テキストを出すノードをいじってるときに、各文字を加工したあとインスタンスに戻したいという動機が出てきました。そういうときにもSample Index, Sample Nearestノードは使えます。
元のインスタンスのインデックスの値を転送することによって各文字をインスタンスに分離することができます。
Sample Indexの基礎的な使い方
Sample Indexノードの各パラメータ
大まかに言うと、どのジオメトリのどの場所のどのインデックス番号のどんな属性値をサンプリングしたいのかを指定するだけです。
- 属性値の型
- 属性値をサンプルする場所(ドメイン:点・面・辺など)
- Geometry…どのジオメトリか
- Value…どの属性値か
- Index…どのIndexの場所なのか
結構細かく指定しなければなりません。Indexには、Indexノードを渡すことでジオメトリ全体の属性値を取得することもできます。

これだけ見てもよくわかんないと思うので、具体的な使い方を以下に示します。
Sample Indexノードで位置を取得
PointsとGridノードを出し、Join Geometryで一緒に表示しています。
Pointsを、Set Positionノードで、位置を変更したいとします。
その位置を、Gridからサンプル(抽出)するためにSample indexノードを使います。
Gridの位置をサンプルしたいので、GridにSample Indexノードをつなげて、そこで得たいValueにPositionを繋げます。
Positionの値は型はVectorで、どこの値かというとGridの各ポイントの値が欲しいのでPointを設定します。
あとは、Set PositionノードのPositionに、Sample Indexノードのアウトプットのvalueをつなげます。

Sample IndexノードにはIndexを入力する欄があり、そこで入力されたindexのポイント(今回Pointを設定したので)の情報がアウトプットから出力されるということです。
上の図では8のインデックスの点の位置情報を取得したので、ポイントのジオメトリがGridの8のインデックスの場所に移動しています。
Capture Attributeノードを使ってインデックス番号を取得
CubeとGridを出してJoinします。
今度は、GridのIndex番号をサンプリングして、Cubeに送ってみます。
Sampling Indexノードに型はInteger、ValueにIndexノードをつなぎます。
値を受け取るCubeにCapture Attributeノードをつなげます(Store Named Attributeノードでも良い)
Capture Attributeは、今回はCubeの各点に値を取得するのでPointと設定。
Sample IndexのアウトプットのValueをCapture Attributeノードに渡します。
Index番号3を指定すると、Cubeの各点に3が入っていることが確認できます。

ここで、Capture Attributeでも値が転送できたじゃないかと思われるかもしれませんが、このやり方だと場所やIndex番号を完全に指定しないと属性値を転送できません。Sample Nearestノードも使うことで、近くの点や辺、面の属性値を転送することができます。
Sample Nearestの基礎的な使い方
Sample Nearestノードの各パラメータ
あるジオメトリから別のジオメトリの一番近い部分のインデックスを取得できます。
- 近い部分のドメイン(点・辺・面…etc)
- Geometry…近い場所を探すジオメトリ
- Sample Position…どこから近い場所を探すか(デフォルトはPositionノードをつないだのと同じ)

一番近い場所のインデックスを取得
PointsとGridを出します。
Pointからみて、一番近いGridの点のインデックスを取得したいので、GridにSample Nearestノードをつなぎます。
これだけで、一番近い点のインデックスを出力してくれるようになるので、PointsにCapture Attributeノードをつなぎ、Sample Nearestノードの出力を渡します。
今ポイントは真ん中にあり、一番近い12番のインデックスが取得できました。

カーブのポイントを、グリッドの一番近い点の位置に移動する
今度は、Starで星のカーブを出して、そのカーブのポイントを、一番近いGridの点の位置に移動させてみます。
Sample Nearestでそれぞれのポイントの一番近い点のインデックスを出力し、それをSample Indexに渡します。そのIndexの点の位置が欲しいので、PositionノードをSample IndexのValueにつなげて、型はVectorにします。
すると一番近い位置の情報が出力されるので、そのままSet PositionノードのPositionにつなぎます。
星の各ポイントが、それぞれ一番近いグリッドの点の場所に移動しました。

インスタンスに分ける
Split to Instancesというノードがあるので、これを使って、散らばったポイントを、いくつかのインスタンスとしてまとめてみようと思います。
五角形のメッシュをだして、そのポイントに近い点をまとめて、5つのインスタンスに分けていきます。

さっきからやってることはほぼ同じで、今までGridから近い点の情報を取得していましたが、今度は五角形のメッシュから近い位置のインデックスの情報を取得しているだけです。
ポイントをばら撒いて、Capture Attributeで、それぞれの点に近い五角形の角のインデックスを取得します。
そのインデックス番号を元にSplit Instancesノードでインスタンスに分けます


ランダムでインスタンスごとに色を分けられるので、マテリアルで色をつけると、左図のように五色にわけることができました。
まとめ
ノードで複数のジオメトリを出していると、今自分は何のジオメトリの値を見ているのか、わからなくなってきます。Fieldのノードが何の値を出しているかの理解も重要になってきます。
Sample Index, Sample Nearestも、抽出したい値のあるジオメトリにつなげて、ある値を取得してくるものなので、どのジオメトリにつなぐかを間違えないように注意が必要です。