見出し画像

Blenderのジオメトリーノードで花火を作る

はじめに

こんにちはとぅなです。今回がBlenderのジオメトリーノードでしだれ花火を作成したのでnoteを書きました。
ここの文章を書いている段階ではわかりませんが、
内容の難易度は、コピーするのであればジオメトリーノード初心者から、
勉強が目的であれば、内容が複合的なもののため少し初学者には向いていないかもしれません。
ただ、概念として重要な内容については太文字で残しておきました。


ノードの概観

ノードの概観は以下のようになります。
1枚目がジオメトリーノードの全体
2枚目がグループ化された内部
3枚目がシェーダーのノードの全体
です。

全体
グループ内
シェーダー

グループ内のシェーダー(2枚目)では、カーブオブジェクトを生成し、必要な情報を格納することが主な目的で、
その情報を元に太さや密度を変化させるのが1枚目の働きになります。

はじめに全体の流れを説明し、次に2枚目のジオメトリーノードについて解説をしていきます。

目標

以下の画像のようなものをつくることを目標にします。

フリー素材.comより

全体の流れ

はじめにしだれ花火を作るために僕が考えたことを記していきます。

  1. しだれ花火の軌道は連続ではない。

  2. 爆発元よりも先のほうが粒が粗く目立つ

  3. 爆発元よりも先の方が線が太い

はじめに、以上の3点を必須の条件に設定し、作成しました。

ここで、1にあげた連続ではないという条件ですが、資料によっては滑らかに軌道がみえるものもあります。これは、長時間露光によるものであるため今回は目標にしませんでした。

次に、作成の流れですが、
最初は花火の軌道を一本のカーブとして作ることから始めます。
その後、そのカーブ上にポイントを作成し、粒を配置することで1つ目の条件がクリアできると分かると思います。
この際に、ポイントの作成に偏りを作ることで2つ目の条件を、
粒の大きさに偏りを作ることで3つ目の条件を達成します。

ここで、始点から終点に向けて重みを付ける方法について考えます。
方法はいくつかあると思いますが、一つの軌道の再現のために複数のカーブラインを作成する関係上、カーブラインに重みをつける方法が一番手っ取り早いと判断しました。

以下は没案になります。

  • Z座標で重み付けをする。
    →初期速度が上向きである軌道に対して有効でない

  • 爆発の中心からX-Y平面上の距離の離れ具合で重み付けを行う。
    →マッピングの必要性から始点と終点の原点からの距離を取得した後にもう一度全体に再計算をする二度手間となってしまう。

後者の案の場合、採用案の弱い部分である離散的である点がクリアされているため余裕があればそちらでもいいかもしれません。

カーブで概形を作成する

ここが、全体の50~55%を占めます。
この段階で行う目標は、

  • 軌道を再現する

  • カーブラインに重み付けをする

の2点です。

今回ひとつひとつの軌道の再現のためにカーブラインを使うため、プログラミングをする方には伝わると思うのですが、2重for文を使う必要が出てきます。要は、繰り返して処理をする必要が2回出てきます。
この時に、

// パターン1
for () {  //リピートノードと同義であると考えていただいて問題ありません。
  // 特定の軌道を選択
  for () {
    // 始点から終点までつなげる
  }
}

// パターン2
for () {
  // 始点から何本目のカーブラインか選択
  for () {
    // 全ての軌道を作成
  }
}

の2パターンの繰り返し方が想定できます。今回はパターン2の方を採用します。これは、重み付けの話に通じるのですが、スプレッドシート上で各カーブオブジェクトに振られた値を確認する際に、

パターン1では、1, 2, 3, …, 30, 1, 2, 3, …, 30
パターン2では、1, 1, 1, …, 3, 3, 3, …, 30, 30, 30のように表示されます。

この時に、1がいくつ存在するか数える可能性が出てくるときにわかりやすいのは後者であるためにこちらを選択しました。

リピートノードの用意

まずは、ICO球かUV球を作成し、ジオメトリーノードを作成。
その後リピートノードを2つ用意します。

まずは、始めのリピートゾーンには、花火の軌道の始点になるポイントの情報を与える必要があるため、ICO球の面にポイントを作成します。

ジオメトリーノード
ビューポート

次に、外側のリピートノードの反復の値を設定します。これは1つの軌道が何本のカーブラインで構成されるかに関わるため、グループ入力ノードと接続して設定できるようにします。初期値は5程度で問題ありません。

ジオメトリーノード

次に内側のリピートノードの反復の値を設定します。これは、軌道の数に依存するため、ポイントの数を受け取るドメインサイズノードを使います。

ジオメトリーノード

カーブラインの作成

カーブラインの作成に移るために連続した軌道を作るために必要な情報を精査します。必要な情報は以下の3つです。

  • 各カーブラインの始点座標

  • 各カーブラインの終点座標

  • 軌道の速度ベクトル

これをノードに落とし込んでいきます。

こんな感じになったと思います。なぜ速度を定数倍するかだけ話して初期値は終わりにします。簡潔に言うと初期速度は、花火の拡散具合に直結するため、ここで定数倍をしないと物足りない結果になることが要因です。

次に値の取得をします。いままでは初期値を入れただけであるため、属性の名前を元に適切なindexから値をとる必要があります。まずは、内側のリピートノードを図のように変化させます。
for文でいう”i++”のような作用です。

次に以下のようにします。

名前付き属性ノードの名前欄はわかりやすさのため入力していますが、保守性のため、左にある文字列ノードから接続してください。
また、名前付き属性ノードとインデックスサンプルノードを使うことでスプレッドシート上の任意の値を取り出すことができるのは必須です。

次に、重要な概念について説明します。
今回カーブラインの出力をジオメトリと統合しませんでした。
これは、ジオメトリは初期値のまま保持し続け、新たに作成したカーブオブジェクトはリピートゾーンのカーブの出力から蓄積したものを手に入れることができるという挙動ができます。
これを用いることで、例えば新たに作成するのがポイントオブジェクトのとき、保存した属性のスプレッドシートが壊れるのを防止できるなど利点が多くあります。

次に値の更新を行います。

こんな感じになります。このとき、ジオメトリ統合ノードの左側の接続先は外側の最初のリピートノードのカーブであり、XYZ合成ノードのZの接続先はグループ入力ノードになります。また、名前付き属性ノードは先ほど作成したものからつないでしまって問題ありません。

以上で以下の図のような見た目になったでしょうか?

カーブラインの重み付け

概形作成の最後の目的に来ました。重み付けというのは、単純に言うとカーブラインが作成されたときに外側のリピートノードが何週目であるかがわかればいいので、

黒いフレームがついたノードを追加し、適切な位置に置けば終了です。

オプション1:軌道のスタートを途中からにする

花火の軌道は、時間経過で爆心から見えなくなるため、それを再現します。見えなくなるといっても累積して計算する必要からカーブ自体は生成し、重み付けにつけた値から外れている場合は出力の対象から外すという手法を取ります。

以上のように接続し、比較ノードのBはグループ入力ノードに新たに接続します。Aは、外側のリピートノードの加算ノードから接続したものです。

オプション2:風の影響を受けるようにする

実際の花火は風の影響で軌道がぶれるためそれを再現します。これは、カーブラインの終点の値を調整することで再現できるため、ノイズテクスチャノードを用いてぶれさせます。

この値ノードは削除してグループ出力ノードに接続することを推奨します。
ただ除算で範囲を狭めた値を足すだけですが、減算でXYZすべてを0.5引く理由だけ記していきます。
はじめにBlenderでは、カラーとベクトルに互換性があります。
RGBの値とXYZの値が自動的に変換できるためです。しかし、カラーの範囲は0~1であるため、そのまま接続すると期待値だと+0.5だけXYZともに歪むことになります。それを防止するため、0.5を引くことで-0.5~0.5の範囲にマッピングして操作をしているという仕組みです。

グループ入力ノードを整理する

最後にグループ入力ノードを整理します。現時点で、このような形になっていると思われます。(ベクトルである必要がないものはfloat型に変更しています。)

"反復"は、一つに軌道に対するカーブラインの数でした。
"A"は一つの軌道のうちはじめのカーブラインの位置でした。
これらは、近い関係にあるため、start, endと変更して上にもっていきます。
上の"ベクトル"は初期速度の倍率を示しているため、火薬量と変更します。
"Z"は、重力加速度を示していたため、重力加速度に変更します。
下の"ベクトル"は風の影響を変えるため拡散に変更します。

これで概形の作成は終了です。

花火を作成する

軌道に太さをつける

一番単純な作業になります。

軌道にポイントを配置する

軌道にポイントを配置し、しだれ花火の粒を再現します。以下のようにノードを配置します。

密度に与える値をカーブラインの重み付けをもとに根本と先端で変化させるようにします。

このようにつなげることで、範囲マッピングで自動的に重み付けの値が変化し、密度の範囲に変換されます。

ポイントに球を配置する

ポイントにICO球を配置します。

スケールの値を重み付けの値を元に調整することで軌道の根本と先端の大きさに変化を与えます。

先ほどのポイントと同じように配置するだけで問題ありません。
ここで、オブジェクトの状態が変化したときのスプレッドシート上の変数の挙動について説明します。今回カーブについていたlevel属性ですが、メッシュ>ポイント>インスタンスとオブジェクトが変化した際に、属性自体の所属も変化します。しかし、カーブのlevelもインスタンスのlevelも同じものという認識があるために、名前付き属性ノードのlevelは、どこに接続しても望み通りの値を提供してくれるようになっています。

マテリアル設定

マテリアルを適用するためにインスタンスを実体化します。インスタンスとは、コピーのようなもので、このままではオブジェクト自体は1つだけであるため、マテリアルをいくら変化させようと全て同見た目になります。

また、名前付き属性格納ノードはモディファイア―の入力値をシェーディングに持っていくために必要になります。

マテリアル設定

シェーディングタブに移動して新たにマテリアルを作成してください。
このとき、ジオメトリーノード上でマテリアルを設定することを忘れないでください。

マテリアルは上記のものを参考にしてください。
ここで、黒体ノードについて説明をして最後にしようと思います。
黒体ノードとは、温度の数値を元に色を決定するもので火と相性がいいのはもちろんのことHSVノードを組み合わせることで、大きく破綻しないグラデーションを作成することができます。

最後に

ここまでお疲れさまでした。前半のボリュームがものすごかったのに加えてnote執筆時にリファクタリングがすすんで多くの改良がなされたため後半の密度が低下したように感じます。
一日で書いたため少し内容がめちゃくちゃな部分や、表現に揺れがあるかもしれませんがご了承ください。

もし、わからないことがございましたら、コメントかTwitter(現X)にてコンタクトを取ってください。

この物好きなジオメトリーノードを扱う人が一人でも増えることを、
ジオメトリーノードの発展に貢献できることを願って締めたいと思います。

以上とぅなでした。

いいなと思ったら応援しよう!