Blender 3.0 の使い方 (16) ジオメトリノード (1)
前 (グリースペンシル) www.mztn.org 次 (ジオメトリノード (2))
Blender 3.0 のジオメトリノードの使い方
Blender 3.0 のジオメトリノードの解説の1回目です。ジオメトリノードはオブジェクトの頂点情報を使って、各種のノードを組み合わせてオブジェクトをプロシージャルに (プログラミング的に) 加工するモデリング手法です。
(この記事とほぼ同じ構成の2.9シリーズ用のジオメトリノードの解説記事(旧版) )
ジオメトリノードは、Blender のこれまでのポリゴンを中心としたモデリング、粘土細工のようなスカルプトによるモデリングに続く第3のモデリング手法といえます。
例えば、植物をプロシージャルな(プログラミング的な)モデリングによって作成すると、森や草原のように非常に多くの物体が存在するようなシーンの作成や、オブジェクト自身が状況によって自律的に形状を決める(成長する)ような事が可能になります。 (これまでも Python を使えばプログラミングによって Blender の操作も可能でしたが、モデリングと呼べるものではありませんでした。)
この記事では、すべてノードの名称など日本語化しないで英語表示のままにしています。 ノードはプログラミング言語の命令や関数のようなものなので、ノードの名称は英語のまま覚えたほうがバージョンアップなどで混乱しなくていいと思います。またメニュー中のノード並び順がアルファベット順なので英語表示のほうが探しやすいと思います。
ばらまく
まず、ジオメトリノードの効果が簡単に確認できる、多くのオブジェクトが散乱したようなシーンを作成する方法です。
まず、1辺が16mの平面を準備します。
「Editor Type」のアイコンをクリックして、「Geometry Node Editor」を選択します。
「New」をクリックすると「Geometry Nodes」という名前のジオメトリノードが生成されます。
入力となる「Group Input」ノードと、出力の「Group Output」ノードが表示されます。 このままでは何も変化しません。
面上にランダムに点を生成
メニューから 「Add / Point / Distribute Points on Faces」をクリックします。 「Distribute Points on Faces」ノードは、バラマキの中心となる機能となっていて、オブジェクトの表面に点(位置)をランダムに配置します。
「Distribute Points on Faces」ノードを「Group Input」と「Group Output」の間に接続すると、平面が消えて、多くの点が表示されます。 「Density」の値を大きくすると点の数が増えます。
ランダムな点に Cube を配置
メニューから 「Add / Point / Instance on Points」を選択して「Instance on Points」ノードを「Group Output」の前に接続します。
メニューから 「Add / Mesh Primitives / Cube」を選択して「Cube」ノードを追加してます。
「Instance on Points」の Instance ソケットに Objectの項目に Cube を設定します。 また平面を複製してもう1つ追加して、元の平面の範囲がわかるようにしています。
「Point Instance」のObjectで指定した立方体が、追加した平面上にばらまかれているのが確認できます。
「Distribute Points on Faces」ノードを「Random」から「Poisson Disk」に変更すると、最小距離を設定することができて、重なったりせず少し均等にばらつかせることができます。 「Random」より「Poisson Disk」のほうが使いやすいかもしれません。
ベジェカーブを追加
オブジェクトモードでベジェカーブを追加して、プロパティのBevelのDepthの値を修正してチューブ状にします。
サイズとローテーションを調整して、原点から上に伸びたような形状とします。 メニューの「Object / Apply / Rotation&Scale」を実行して角度を0、スケールを1に設定します。
アウトライナーから BezierCurve をノードエディタ上にドラッグアンドドロップすると 「Object Info」が追加されます。「Point Instance」のObjectの項目に Cube の代わりに BezierCurve を指定すると、平面上に多くの曲線が出現します。
これらの BezierCurve をランダムなサイズに変更するために、「Instance on Points」ノードの Scale ソケットに「Random Value」ノードを追加します。
「Random Value」ノードの設定を Float にして、Min と Max に適当に値を入れると、個々のオブジェクトがバラバラのサイズになるのが確認できます。
次に「Random Value」ノードを Vector 型にして、「Instance on Points」ノードの Rotation ソケットにつなぐと、各軸ごとの回転範囲の設定で個々のオブジェクトの角度を変化させることができます。
「Random Value」ノードをもう一つ追加して、角度とスケールの両方を乱数で変化させると、バラバラ感がさらに強くなります。 上の「Random Value」ノードは「>」をクリックして縮小表示にしています。
「Distribute Points on Faces」ノードと「Instance on Points」間のノードを複製して、「Join Geometry」ノードを介してGroup Outputに結合します。 上の「Instance on Points」に立方体(Cube)、下の「Instance on Points」にベジェカーブを設定します。石ころと変な生物っぽくなってきました。
ノード構成を拡大して表示しました。scale も Vector 型にして、各軸のサイズを変えています。「Random Value」ノードの設定は色々試して、いい感じの値を探して下さい。
マテリアルで着色し、 Eevee で表示すると、石と草っぽい感じになりました。 平面2つと1つの立方体、1つのベジェカーブで出来ているとは思えませんね。
同じノードをもう1列追加して、別オブジェクトとして作ったキノコ (Cylinderという名前) をシーンに追加してみました。「Distribute Points on Faces」から「Instance on Points」を複製して「Join Geometry」でまとめて「Group Output」に接続しています。
草の間にキノコが生えたようなシーンの出来上がりです。シーン上に約2000のオブジェクトが存在していますが、元は3つなので軽快に動作します。
ベジェカーブをジオメトリノードで草に加工
ベジェカーブをチューブ状にしましたが、これでは草には見えません。ベジェカーブにもジオメトリノードを設定して草のような形状にしてみましょう。 ベジェカーブの半径を「Curve Parameter」と「Float Curve」ノードを使って先に向かって細くなるように長手方向に変化させます。「Curve Parameter」はカーブの始点から終点に向かって 0 から 1 に変化します。 その値から「Float Curve」で必要な値に変換します。 「Curve to Mesh」に「Curve Line」をつなぐとチューブ状ではなく、薄い形になります。
少し草のようになってきました。ジオメトリノードを使うと、このように数が多くて少しずつ状態の異なるオブジェクトが簡単に作成できます。 1つのオブジェクトをインスタンスの形で複製すると、数が多くても処理の負荷はあまりかかりません。 おそらくBlender内部の処理に関して、CPU から GPU への頂点情報などの転送が一個分だけですみ、GPU側で形状を複製するためでしょう (しらんけど)。
頂点の位置と色の操作
Dynamic Outlines with Blender Geometry Nodes and Eevee というサイトで紹介されている2つの10分程度の動画は、Blender 2.93 のジオメトリノードのアトリビュートの解説として優れたものです。 しかし、Blender 3.0以降、ほとんどのアトリビュートノードは廃止になったため、これらの動画はBlender 3.0では使えなくなりました。
この記事では Blender 2.93 のアトリビュート版ジオメトリノードから Blender 3.0 のジオメトリノードに変換したものを示します。 2.9シリーズ用の前の記事 と比べるとノードの構成が全く別物になっています。
立方体だけを移動させてレンダリングした動画を示します。下の平面は何も動かしていません。 ジオメトリノードを使って、立方体の移動に伴って頂点位置と色を自動的に変化させています。この動画の平面の頂点数は、色の変化をきれいにするため、記事より4倍に増やしています。
最終的に完成するノード構成の全体像です。 Blender 2.93版のジオメトリノード と異なって分かりやすくなっています。
一番上の列は入口となる「Group Input」、頂点の位置を設定する「Set Position」、出口となる「Group Output」があります。
「Set Position」の Offset ソケットに相対位置、「Group Output」の Color ソケットに色を出力しています。
それらの相対位置と色を求めるためのノードが下の部分に配置されています。 左下の「Object Info」と「Geometry Proximity」で立方体と平面上の最も近い頂点との距離を求めて、計算で必要な値に加工しています。
基本は左側の入力ソケットから入った情報が加工されて右側のソケットに出力されるだけです。
立方体と平面の準備
まず、最初の立方体に加えて、平面を追加します。 立方体を選択して編集モードから Scale を 0.1 にして、1辺が0.2mの立方体を準備します。
次に平面を選択して、編集モードから「Edge / Subdivide」して平面を分割します。
分割数は最大の 10 としておきます。
もう一度、「Edge / Subdivide」して、分割数を 7 とします。 これで平面は88 x 88に分割されます。
立方体と平面上の頂点との距離を色に変換
オブジェクトモードで平面を選択した状態で、ジオメトリノードエディタを開きます。 「New」をクリックしてジオメトリノードを作成します。
立方体と平面上の頂点との距離を求めるため、「Object Info」、「Geometry Proximity」、「Color Ramp」ノードの3つを追加して接続します。
- アウトライナーの「Cube」を「Group Input」と「Group Output」とは離れた位置に、ドラッグアンドドロップすると「Object Info」 ノードが追加されます。
- メニューの「Add / Geometry / Geometry Proximity」から、「Geometry Proximity」ノードを追加して、「Object Info」の Geometry ソケットと「Geometry Proximity」の Target ソケット間を接続します。
- 「Geometry Proximity」の Distance ソケットを「Add / Color / Color Ramp」から「Color Ramp」ノードを追加して接続します。
- 「Color Ramp」の Color ソケットを「Group Output」の空きソケットに接続するとGroup の出力に 「Color」が作成されます。
- プロパティの「Object Data Properties」タブの「Vertex Color」に「Col」という名前が存在することを確認します。
ジオメトリノードを作成すると、プロパティの「Modifier Properties」タブに「GeometryNodes」モディファイアが追加されています。 「Output Attributes」の Color に頂点グループの「Col」という名前を設定します。
ジオメトリノードのカラー出力をマテリアルに反映
シェイダーノードエディタに「Attribute」ノードを追加して、名前を「Col」としてベースカラーに接続します。 これで、ジオメトリノードで出力した色がマテリアルに反映されます。
3Dビューポートをレンダーモードに切り替えると中心部の平面が黒くなっていることを確認できます。 立方体の近くの平面の頂点カラーが黒く表示されて、立方体と平面の距離が0に近いことを示しています。 立方体から離れるほど距離の値は大きくなりますが、「Color Ramp」ノードの出力は 0 から 1 の範囲に制限されます。
立方体からの距離に応じた同心円を求める
- 「Geometry Proximity」の次に「Math」ノードを追加して、演算を「Multiply」に設定します。
- 乗算する数値として 30 を設定します。
- その結果を「Math」ノードの「Cosine」につなぐと、三角関数のコサインによって、出力は ±1 の範囲で周期的に変化します。
- それを「Math」ノードの「Multiply Add」で0.5倍して0.5を加えると、0から1の間を周期的に変化する結果が得られます。
- 「Color Ramp」ノードで色の変化の仕方を設定すると、立方体からの距離に応じて同心円上の縞が確認できます。
縞の数を変更する(Reach)
- 「Group Input」に Reach という名前の入力ソケットを作成して、「Geometry Proximity」ノードの後ろに追加した「Math」の「Multiply」で乗算します。
- Reach に設定した値を大きくすると、距離 * Reach が大きくなり、コサイン関数に渡る値が大きくなるため、縞の数が増える向きに変化します。
波を作る
- メニューの 「Add / Geometry / Set Position」を選択して「Set Position」ノードを「Group Output」の前に挿入します。
- 「Math」の「Multiply」と「Add / Vector / Combine XYZ」の 「Combine XYZ」ノードを 「Set Position」ノードの Offset ソケットに接続します。
- さらにコサイン関数の結果を (0 - 1) の範囲に変換したものを、「Multiply」の入力側につなぎます。
- コサイン関数の周期的な値が「Set Position」のオフセットの Z 値(高さ)に入力されるため、平面の頂点は波型に変形します。
波の高さを調節する(Height)
「Group Input」に Height という名前の入力ソケットを作成して、「Combine XYZ」の前に追加した「Multiply」に接続します。 Height の値を大きくすると、波の高さが大きくなります。
波の高さに変化をつける
Height を接続した「Multiply」の前にもう一つ「Multiply」を追加します。 ここでは 1.0 を乗算しているだけなので、平面の形に変化はありません。
- 上の 1.0 が設定されていた「Multiply」のソケットに追加した「ColorRamp」をつなぎます。
- 「ColorRamp」の前に「Math」の「Subtruct」を追加して、1.0 程度の定数から距離 * Reach を減算します。
- 距離 * Reach の値が定数より大きく(遠く)なると減算の結果は負になり、「ColorRamp」を通すと 0 になります。 結果として遠くなると Height は 0 に近づいて波の高さは低くなります。
プロパティのモディファイアタブから Reach と Height をコントロールできるようになります。
最終的なノード構成を確認
以上のジオメトリノードの構成にメモを書いて見ました。
- (1) Reach 入力で波の間隔を設定
- (2) ±1 を 0 - 1 に変換する定石
- (3) 波の消える距離を設定
- (4) 高さの変化の仕方を調整
- (5) 周期的な値(0 - 1)を乗算
- (6) 波の高さを乗算
まだ他にも多くの種類のノードが用意されています。 色々な使い方が発明されるのでしょうね。
Blender 2.8 - 4.3 の使い方 [目次]
- (01) インストールと日本語化
- (02) 画面構成とモード
- (03) オブジェクトモード
- (04) 球と円柱でモデリング
- (05) スカルプトモード
- (06) 編集モード
- (07) リトポロジー
- (08) Python スクリプト
- (09) マテリアル (1)
- (10) マテリアル (2)
- (11) マテリアル (3)
- (12) アーマチュア(ボーン)
- (13) Rigifyによるリギング
- (14) パーティクルヘア
- (15) グリースペンシル
- (16) ジオメトリーノード (1)
- (17) ジオメトリーノード (2)
- (18) カメラ
- (19) ジオメトリーノード (3)
- (20) 新ヘアシステム Hair Curves
- (21) ヘアカーブの進化
- (22) Vector Displacement Mapブラシ
- (23) アセットライブラリ
- (24) シミュレーションゾーン
- (25) ボーンコレクションとRigify