Blender GeometryNodeでUV座標を投影する方法

Blender Geometry Nodeにおいて、他のオブジェクトのUV座標を取得する方法がわからなかったため、調査しました。

やりたいことは以下になります。

  • オブジェクトAとオブジェクトBが存在し、オブジェクトAのそれぞれの頂点からもっとも近くにあるオブジェクトBの平面上の点のUV座標を取得する

  • そのUVを使用してShaderでテクスチャを適用する

(最終イメージ例)

基本的なノード構成

Aの各頂点からもっとも近いBの表面上の点を探し、その点のUV座標を頂点のUV座標とすることを考えます。 基本的なノード構成は以下のようになります。

SampleNearestSurfaceで頂点からもっとも近い点のUV座標を取得し、Aのアトリビュートとして保持(Store Named Attribute)します。

分かりにくいのがPositionのノードです。Positionのノードには特に入力が入っておらず、それがAの頂点のポジションなのか、Bの頂点のPositionなのか、それを示す必要があるように思われますが、特にそうした設定はありません。 ただ、この場合、Aの頂点のポジションが正しく使用されます。なぜそうなるかは詳細は省きますが、以下のドキュメントに記載されていました。

フィールド — Blender Manual

また、「謎技研」さんのブログの解説もわかりやすいです。

【Geometry Nodes】フィールドって何?PositionやIndexの使い方【Blender】 | 謎の技術研究部

AのShaderは以下のようになります。

Attributeノードを使い、GeometryNode内で作成したUV座標を使用しています。 UVMapというAttribute名で保存しているのでなくても問題ないのではないかと考えたのですが、これがないと正しく動作しませんでした。

テクスチャ画像はBと同じものを使用しています(sample_picture.png)

ここまでの結果はこのようになります。

AやBを動かしても投影が変更されません。

これは、AやBのローカル座標でしか内部の計算を行っていないためです。

画面上での位置座標を反映した構成

Aの動きに対応させる部分、Bの動きに対応させる部分は以下のようになります。

Aの部分は、各ポイントに関して、自ノードのTransform情報を取得し適用しています。 簡単なノードがないかと探したのですが、見つけれず、Scale,Rotate,Translateそれぞれノードで構成しています。

BはTransformGeometryがあったため、それを適用しています。

この結果がこちらになります。

サンプルのダウンロード

サンプルのダウンロードは以下から行えます

20230315 - Google ドライブ

次回

次回は、さらにこれを発展させていく予定です。