こんにちは|こんばんは。カエルのアイコンで活動しております @kyamaz です。
はじめに
数学的な対象を Blender の Geometory Nodes を使って扱う方法の紹介は動画ではありますが、Qiitaのエントリはあまり見かけません。下記のYouTube動画を参考にしてマンデルブロ集合を立体的に描いてみましょう。
本稿を参考に Geometory Nodes を通すと下記のようなモデルが描けます。参考にした動画では、マンデルブロ集合特有の縞模様になる色付けやアニメーションまで解説がありますが、ここではモデリングの解説記事になります。
(Cameraの情報:Location X=6m,Y=-5m,Y=4m; Rotatuin X=60°,Y=0°,Z=50°/Lightの情報:Sun)
Blender Geometry Nodes で描く
まず最初に、Scene Collection に Plane Mesh を追加します。[3D Viewport - Object Mode] にて「Add->Mesh->Plane」で追加し、[Outline - ViewLayer] にて名前を「mandelbrot」に変更しておきます。
このオブジェントを選択した状態で [Geometory Node Editor - Modifier] の「+NEW」でモディファイアを追加し、この名前を [Properties] にて「mandelbrot_displace」としておきます。
Grid を準備する
複素平面をXY軸にマッピングするためのGridを準備します。いくつかの定数を次のように定めて利用します。
- SizeX:PlaneのX軸のサイズ
- SizeY:PlaneのY軸のサイズ
- VertecesXY:PlaneをGridにする分割数
- Scale:倍率(1未満で指定するとZoomIn、1以上でZoomOut)
- C0:描画中心の複素数の座標(細かく指定できるように小数点以下3桁ずつを
C0_upper
とC0_lower
で指定、$c_0=0.256679+0.000875 i$)
次の「Named Attribute」にそれぞれの定数の値を保存します。
-
gridsize_x
:: Float <- SizeX -
gridsize_y
:: Float <- SizeY -
scale
:: Float <- Scale -
c0
:: Vector <- C0_upper and C0_lower -
uv_map
:: Vector <- Gridより(本稿では利用しない)
パラメーターを初期化する
GridのなかのPointごとに処理されますが、そのPointに対応する複素数を上記の定数を使って求め、「Named Attribute」の c
:: Vector にその値を保持します。また変数 z
:: Vector の初期値にも c
を代入しておきます。
その前に、繰り返し回数の iteration_count
:: Integer と、発散するかのフラグ isIn
:: Boolean も初期化しています。
ループで計算処理を行う
前のキャプチャの一番右にある Iterations は階層的に処理を記述しています。次の2つのキャプチャのように。Iterations
には iterations_group
を 10 回分繰り返し、その中で Iteration
を更に10 回分繰り返すようにします。つまり、10 × 10 = 100 回の繰り返し処理となっております。
z^2+c を計算する
$ f(z) = z^2+c $ を計算するパートは次のようになります。escape condition
にあるように、isIn
フラグと複素数 z
の length
$|z|<2$ かどうかで処理を分けています。どちらも真(true
)のときは、
-
iteration_count
を+1
する -
z
をz^2+c
の計算結果に変更する
の処理をします。いずれかが偽(false
)のときには、isIn
を偽 false
にして、それ以外(iteration_count
とz
の値)は変更しません。
このPointごとに計算した値を確認したい場合は、次のキャプチャのよりに [Spreadsheet - Evaluated] にて確認することができます。
繰り返し回数を高さに反映する
$|z|<2$を満たさなくなるまでの繰り返し回数iteration_count
を Grid の Point のオフセットとして計算します。smooth coloring
と shader preparation
で、そのオフセットの元となる値を求めています。
displace
のなかの [Set Position] で Offset を設定しています。最後に、 [Set Shade Smooth] で表面をスムーズにする処理を行い、完成です。
オフセットを求める際に、次のような計算を行なって、iteration_count
に足しています。z
の値を使うことでより滑らかになるようです。
以上で、Geometory Nodes で設定する全体像となります。
おわりに
は Blender がほぼ初心者でショートカット等の操作が頭に入っていないため、作成にはとても時間がかかってしまいましたが、試行錯誤しながら作成していけますし、数学の対象を 3D で表すのには、Blender は楽しいツールだと感じました。また他にも Python コードも使えますので、[Scripting] でも似たようなモデリングも可能ではないかと思います。本稿とは違う手法を試してみるのも面白いのではないでしょうか。
本稿の環境
本稿のために使用した環境は以下となります。
- macOS: Sonoma 14.5 (chip: Apple M1)
- Blender: 4.2.0
- PYTHON INTERACTIVE CONSOLE 3.11.7 [Clang 15.0.0]
ご一読いただきまして有り難うございます。
(●)(●) Happy Hacking!
/"" __""\