見出し画像

ジオメトリノードでペンデュラムウェーブを作る

※Blender 3.2.2で制作しています。

ペンデュラムウェーブとは

紐の長さの異なる振り子を並べて動かしたときに現れる波のような動きのことです。
参考動画↓

この動きがおもしろいので、ジオメトリノードの練習もかねて作ってみたいと思いました。

完成品とノードの全体像

今回つくったものはこのような感じです。

注意点として、振り子の動きは単振動(X座標がsinの値に応じて動くだけ)にしてあるのと、紐は省いています。

苦労したところ

先に書いておきますが、振り子の色をグラデーションにするのがなかなかできず困っていました。結局「属性キャプチャ」ノードを挟んでドメインを「インスタンス」にすることでうまくいったのですが、正直なんでこれで上手くいっているのかまだよくわかっていません。
そのあたりの実装をもっとスマートにできそうな気もしているので、もしより良い方法を知っている方がいましたら教えていただけると嬉しいです。

制作手順

ジオメトリノードの新規作成

blendファイルを作成したら立方体を置き(結局使わないのでどんなメッシュでもよい)、Geometry Nodesタブにてジオメトリノードを新規作成します。
一応この時点でマテリアルプレビューモードにしてあります。

振り子となるICO球を置く

今はグループ入力は使わないので削除しておき、ICO球を置きます(これが振り子になります)。
スムーズシェードをかけたら、今のうちにマテリアルを作成し設定します(マテリアルの各パラメータはそのままでよい)。
そして、少し大きいのでトランスフォームでスケールを調整します。お好みの大きさにしてください。

メッシュラインで並べる

「メッシュライン」ノードと「ポイントにインスタンス作成」ノードを追加してICO球を並べます。並ぶ個数はメッシュラインの「数」の値によって決まります。

ここで、並べる個数をモディファイアから制御できるようにしたいと思います。

(ジオメトリノードエディターの上で)Nキーを押すと開くサイドバーにあるグループタブから入力ソケットを追加します。
「入力」のところにあるプラスボタンを押して、タイプを「整数」にします(選んだらIntegerという表記になります)。
そして、「グループ入力」ノードを追加して「入力」ソケットをメッシュラインの「数」につなぎます。
そうすると、画面右側のモディファイアープロパティにInputの入力欄が現れ、数値を変更するとICO球の個数が変化していることが確認できると思います。

振り子を動かす

キモとなる動きの実装です。小さくて見づらいですが先に全体像を出しておきます。数式部分を拡大したものは後にあります。

「ポイントにインスタンス作成」ノードとグループ入力の間に「インスタンス移動」ノードを挟んでいます。そこの「移動」に「数式」ノードなどで色々計算した結果を「XYZ合成」ノードを通して入力しています。
そのあたりのノードはこのようになっています。

色々細かい数字がありますが、流れとしては現在のフレームに対応したsinの値を計算して各ICO球に渡しています。また、インデックスノードで各ICO球の動く速さ(周期)をずらしています。今回の場合は後ろの方が速くなるようにしています。
サインノードの前で1.571という値を減算していますが、これは$${\pi/2}$$です。値を入力するとき「pi / 2」と入力すると計算してくれます。
計算内容を数式にすると、現在のフレームを$${F(\ge 1)}$$、ICO球のインデックスを$${I(\ge 0)}$$としたとき、

$$
\sin(\frac{F - 1}{10}(1+\frac{I}{10}) - \frac{\pi}{2})
$$

となります。1フレーム目には全て左端にあり、インデックスごとに係数が0.1ずつ増えていくようにしています。また、フレームを直接渡すと速すぎたので10で除しています。このあたりはお好みで調整してみてください。

マテリアルの設定をする

次に、各ICO球をグラデーションさせるためにマテリアルの設定をします。

Shadingタブに移ってMaterialの設定をします。カラーランプを虹色にしてプリンシプルBSDFにつなげるのですが、以下の手順で虹色を作ることができます。

  1. カラーモードをHSVにする

  2. 色の補間を時計回りにする

  3. 左のスライダーの色をHSV(0,1,1)、右のスライダーの色をHSV(0.99,1,1)にする

できあがったら、係数を動かすことでICO球の色が変わると思います。
この係数に各ICO球のインデックスを入力すればグラデーションができそうなので、その実装をしていきます。

インデックスとカラーランプの係数を対応させる

マテリアルからインデックスを利用するためにはグループ出力のソケットを使う必要があるので、先に追加しておきます。

個数を入力するときにしたのと同じような手順で、サイドバーの「出力」にあるプラスボタンを押して、名前を「Fac」にします。そうしたらグループ出力に「係数」が現れています。また、モディファイアーの出力属性に現れた「Fac」に「fac」と入力します(変数名みたいな感じだと思います)。

これでマテリアルから係数を利用できるようになったので、Shadingタブに移ってノードを追加します。

「属性」ノードを追加し、係数をカラーランプにつなげます。名前の入力欄があるので、「fac」と入力します。

これでジオメトリノードのグループ出力の係数を変更すると色が変わる、と思ったら変わらなかったのですが、「インスタンス実体化」ノードを挟むことでちゃんと変わってくれるようになりました。
(インスタンスとは何なのか全然わかっていないのでこれから勉強したい)

あとはインデックスに応じて係数を変化させるだけですが、次のようにノードをつなげることでできます。

インデックスやグループ出力はノード全体の左端あたりでも使用していますが、リンク(線)を引っ張ってくると見づらいので新しく置いています。
除算ノードでインデックスを全体の個数(Input)で除することで、0/20,1/20,2/20,…の値が係数に出力されていくようにしています。なので、個数が増えてもいい感じにグラデーションできるようになっています。
ちなみに、冒頭にも書いたとおりこの辺りの挙動がよくわかっていません。たまたま動いた感じなのでちゃんと勉強したいです。

レンダリングする

全体の動きは完成したので、あとはレンダリングするだけです。お好みの設定でかまいませんが、例として今回作ったものを書いておきます。

ワールドプロパティのカラーは白(HSV(0,0,1))にします。

レンダリングエンジンはEeveeで、カラーマネジメントのビュー変換は標準にしておきます(背景の白を明るくするため)。

フレームレートは30fpsにして、終了フレームを629にします(振り子がぴったり揃うのがこの辺り)。

カメラのトランスフォームはこのようにして、

振り子の大きさが同じに見えるように平行投影にしました。ついでに振り子の個数を30に増やしてあります。

あとはアニメーションレンダリングすればおもしろい動きを見ることができます。ありがとうございました。




この記事が気に入ったらサポートをしてみませんか?