🐔

【Blender】ゲームVFXメッシュ球・ドーム・リングジェネレータの作り方 ジオメトリノード編

2023/09/02に公開

◯概要

【もここのBlender VFXメッシュ自由研究】
今回はBlenderでのプロシージャルな球、ドーム、リングメッシュジェネレータを作ってみたので備忘録をメモしておきます。

球、ドーム、リングと書いていますが、どれも球を削らないか、下を削るか上下を削るかでおんなじような感じなので統合下システムです。

◯環境

Blender 3.4.1(メッシュ制作)

◯今回球メッシュを作る作戦

・UV球を追加(ジオメトリノード)
・球の上下を削除

+UV設定
+頂点カラー、アルファ設定
+入力値をパラメータ化
+ピボットの設定
+ノーマル設定
など

◯球、ドーム、リングメッシュジェネレータの作り方(ジオメトリノード)

今回作るノードの全体像はこんな感じです。

ーーー
UV球を作る部分に関しては、前回のUV球ジェネレータと同じです!

▼1.適当なメッシュを作る

ジオメトリノードを適用するためのメッシュを追加します。

・「Geometry Nodes」ワークスペースでPlaneなど適当なメッシュを追加します。(このメッシュ自体は使わないので正直なんでもOK)

▼2.わかりやすくリネーム

わかりやすく名前をつけておきましょう。
今回はわかりやすく「SM_halfSphereBlenderGN_000」とリネームしておきました。
(もしくはリング「SM_ringBlenderGN_000」など)

▼3.新規GeometryNodeを作成(以降ジオメトリノードの作業です)

・「New」ボタンをクリックして新規ジオメトリノードを追加
どのメッシュで使われているかわかりやすいように「SM_halfSphereBlenderGN_000」とリネームしておきました。
(もしくはリング「SM_ringBlenderGN_000」など)

▼4.ノードでUV球を作成する

・「Shift + A」でノード検索 → 「UVSphere」でUVスフィアを錬成できます。

今回はこれを魔改造していきます!
(流用大事!楽できるところは楽していきましょ~(^ ^))

▼5.球の上下を削除する

「真ん中から指定距離離れたら削除する」という作戦でシステムを作っていきます。

<上を削除>
・「Delete Geometry」「Greater Than」「Separate XYZ」「Position」ノードを↓のように繋ぎます。
「Greater Than」のBの値を調整すると指定したより高い位置が削除されます。
(A > Bの場合に削除されるはず…なんですが微妙に想定と違う挙動をしているような気が…。まぁ良しとしましょう。)

<下を削除>
・同じように「Delete Geometry」「Less Than」「Separate XYZ」「Position」ノードを↓のように繋ぎます。
「Less Than」のBに「-0.5」などマイナスの値を入力すると、指定したより低い位置が削除されます。(A < Bの場合に削除。)

▼6.パラメータ化(パート1)

ここまでの調整したい値をパラメータ化しておきます。
やり方はジオメトリノードで球のジェネレータを作ったときと同じです!

ーーー
<入力の削除>
・まず、「N」キーでサイドメニューバーを開きます。
「Input」という項目が、入力パラメータです。

・最初からある「Geometry」は、はじめに仮でおいたPlaneメッシュのことなので削除してしまってOKです。右の「-」ボタンから削除できます。

<パラメータの追加>
・「+」ボタンでパラメータを追加できます。

・今回は球の分割数(SegmentsとRings)用に、
以下のようなパラメータを追加します。
 →「Integer:整数」
 →名前
 →デフォルトと最大最小値を設定
・モディファイアプロパティでInputsの値を設定できます

・Group InputでInputsのパラメータを使用できます。
「Segments」と「Rings」に繋げばOKです!

・パラメータの値を変えるとUV球の分割数が変わります。

・「TopDeleteHeight」のFloatパラメータで、上部分の削除高さを指定できるようになります。

・「BottomDeleteHeight」のFloatパラメータで、下部分の削除高さを指定できるようになります。

これで色んなお椀型やリング型などもつくれるようになります!!!

基本の形はこれで良いんですが、ここからのUV設定が(正直だいぶだいぶ)面倒くさいです…。ゴリゴリ計算していきます。

▼7.UV設定に使う値ptnumなどを事前にキープしておく(少し面倒)

この後のUV設定のステップで、Houdiniでいうptnumなどいくつかの値を使いたいので、わかりやすいように名前を付けてキープしておきます。

<ポイント番号(Houdiniでいうptnum)>

・「Store Named Attribute」「Index」ノードでポイント番号(ptnum)をキープ。

「Store Named Attribute」の設定

Integer
Point
「ptnum」
ーーー
今回は「Point」アトリビュートに対してIndexノードを繋いでいるので、ポイントのインデックス番号を取得、キープしています。

<ポイント総数(Houdiniでいうnumpt)>

・「Store Named Attribute」「Domain Size」ノードを↓のように繋いでポイント総数(numpt)をキープします。

「Store Named Attribute」の設定

Integer
Point
「numpt」

<球の上下削除後の行数>

UVを正規化するときに、球の上下を削除した行数が必要かなと思ったので、
今回はとりあえず「trim_rows」という名前で計算した値をキープしておきました。
・「Store Named Attribute」「Add」「Floor」「Divide」「Modulo」「Named Attribute」「Group Input : Segments」ノードを↓のように繋ぎます。

「Store Named Attribute」の設定

Integer
Point
「trim_rows」

「Named Attribute」の設定

Integer
「numpt」

正直いくつか複雑なことをしているのでそのまま真似するだけでも全然OKです。
興味ある人は↓を参考までに。

(この計算の考え方 スルーでもOK)

・横列4、縦行5で考えてみました。この場合のポイント総数は14です。
(上下に1ポイント x 2) + (間に4ポイント x 3行) = 2 + 12 = 14ポイントです。

<まずは上下が削除されていない場合の行数>
・上の例の場合、ポイント総数「14」、横列「4」から → 縦行「5」が求まれば良いかなとざっくり計画。

とりあえず割ってみます。
14 / 4 = 3 あまり 2

なんとなく「商」と「あまり」を足せば、「縦行」の値が出せそうですね。
あまりは「Modulo」ノードで求められます。

<上 or 下どちらかが削除されている場合の行数>
ひとまず上の極のポイントが削除された場合を考えてみました。
この場合はポイント総数「13」になります。

・同じようにとりあえず割ってみます。
13 / 4 = 3 あまり 1

これも「商」と「あまり」を足せば、削除後の「縦行」の値が出せそうです。

ーーー
ということで、上下を削除した場合、しない場合どちらも
Floor((ポイント総数 / 横列数)) + (ポイント総数 % 横列数) = 削除後の縦行数

の計算式で求められそうというのがわかりました。
:::

▼8.マテリアル適用

これは球ジェネレータのときと同じでOKです。

以前の記事で作成した汎用マテリアルを適用していきます。
まだ作ってない場合は↓を作っておきましょう。
https://zenn.dev/animamococo5656/articles/63190887887aa7

・「Set Material」のノードを繋いで、作っておいた「MT_VFXMeshUVMap_Checker」を適用しておきます。
このマテリアルの「UVMap」と「color」アトリビュートにジオメトリノードから値を送ります。

▼9.UVを設定する(少し面倒)

上下削除のパターンにも対応するとなると、球のときのように単純にはいきません…。
正直この辺はBlenderの知識うんぬんではなく、単純に結果を見ながら計算のトライアンドエラーかなと思いました。ちょっとというか結構面倒くさいです…。

ーーー
・ひとまず、球のときのUV設定を適用してみました。

横(X)方向はそのままで良さそうなので、この縦(Y)方向を対応していきます。
ちょっとややこしいですが全体像は↓の通りです。



(この計算の考え方 スルーでもOK)

UVを正規化する作戦(これを一番忘れてしまいそうなので、備忘録としてメモしておきます。正直数日たっただけの今もほぼ忘れているので、頑張って思い出します…(_ _;)。)
わかりやすいように少し縦の分割数を増やして考えてみます。

・上下削除後のUVは、正規化した後の結果が↓のような状態になれば良さそうです。
上下削除後の縦行数が5の場合、分母の「4」 = 「縦行数5 - 1」で計算できそうですね。

・実際にジオメトリノードで組むとこんな感じです。

何行目かは「ポイント番号(ptnum) / 横列分割数(Segments) = 行数 あまり n」なので、Floorノードで商だけ使っています。

ーーー

(一度システムを作ってしまえばパラメータ調整でUVが自動展開されるので便利ではありますね。ただ、他の形状の場合はそれに合わせてまた別のUV展開のシステムを作る必要はあります。前のらせんメッシュも全く別でしたからね。)

▼10.頂点カラー、アルファ設定

これも前に作った球ジェネレータと同じです。

「Store Named Attribute」「ColorRamp」ノードを追加して、色を設定しておきます。
「Store Named Attribute」はColor、Pointにして、「color」の名前でキープしましょう。

▼11.(機能追加)サイズ変更

「Scale Elements」「Vector」ノードを追加して、↓のように繋ぎます。

ポリゴンモデリングと同様にノードでも全体のスケール調整ができます。
ジオメトリノードの場合はこっちのほうが便利です!

▼12.(機能追加)ピボットをバウンド最下部に合わせる

リングメッシュでピボットをメッシュの最下部に合わせたい場合もあるので、機能追加しておきます。
・「Transform」「Switch」「Multiply」「Bounding Box」ノードを繋いで↓のように繋ぎます。

Switchノードは、「最下部にピボットを移動のオンオフ」を切り替えられるように、後でパラメータ化するために繋いでいます。

▼13.(機能追加)不要なアトリビュート削除

・「Remove Named Attribute」ノードで不要なアトリビュートを削除しておきましょう。
「ptnum」「numpt」「trim_rows」「uv_map」あたりの途中キープした値は削除しました。

↓詳細はこちらにメモしてあります
https://zenn.dev/animamococo5656/articles/3792ec04b5279d#▼9.(機能追加)不要なアトリビュート削除

▼14.パラメータ化(パート2)

追加で調整したいものに関しては、パラメータ化しておきます。
・「Scale」「Pivot Z Min」のパラメータを追加しておきました。

・「Group Input」ノードでそれぞれ接続しておけばOKです。
(「Ctrl + H」キーで不要なパラメータは非表示にしておけばスッキリして良いです。)

◯FBX書き出し準備

書き出し設定をしていきます。

↓参考
https://zenn.dev/animamococo5656/articles/e2c4d32d6f7dfd
 ・1.編集メッシュを複製
 ・2.ジオメトリノード適用
 ・2.5.ノーマルの設定
 ・3.トランスフォームのフリーズ
 ・「▼4.UVアトリビュート適用」
をすべて行いましょう。

◯まとめ

試してみた感じBlenderでもHoudiniでいう「ptnum」なども制御できるので大抵のことは、アイディア次第でできそうだなと思いました!

が、Blenderノードの機能を調べながらひたすら計算の連続で、仕組みづくりに1週間とかかかってしまいました…。(特にBlenderでのアトリビュートの制御方法がわかるまでにむっちゃ時間がかかりましたね)

ジェネレータを一度作ってしまえば、使い回せるので次回からパラメータ調整で作れる点は良いですが、正直色んなパターンを考えながらジェネレータを作る時間分ポリゴンモデリングであればもっと早く、作れたかなと思いました笑

ジェネレータの使いまわし、量産をするのであればありかもですね。

ひとまず今回はこんなところで!

Discussion