[Unity]マンデルブロ集合/ジュリア集合を描くシェーダを作る

無題
Pocket

Unity上でマンデルブロ集合を描くためのシェーダを作りました。

 

無題

 

複素数の勉強

マンデルブロ集合を理解するためには複素数の知識が必要なので、復習しておきましょう。

数学は付け焼き刃なので、間違っている所があったらTwitterなどでツッコミを入れてもらえると嬉しいです。

 

虚数

二乗すると-1になる値をiと表記し、「虚数」と呼びます。

i2 = -1

 

複素数

実数a, bと虚数単iを用いて表せる式表せる数「複素数」と呼びます。(※”式”ではなく、”数”ではないかというツッコミを頂いたため修正しました。)

a + bi

 

複素平面

直交座標(x, y)に複素数x + yiを対応させた平面のことを「複素平面」と呼びます。

例えば、3 + 4iなら(3, 4)の座標、 10 + 24iなら(10, 24)の座標を表します。

 

 

複素数の積

複素数の積は回転を表します。

 

複素数C1 = x1 + y1iの原点からの距離をr1、原点からの角度をθ1

同じく複素数C2x2 + y2iの原点からの距離をr2、原点からの角度をθ2、とした時、以下の式が成り立ちます。

C1C2

=  r1 ・ r2 ・ (cosθ1 + isinθ1) ・ (cosθ2 + isinθ2)

r1r2(cos(θ1 + θ2)+ isin(θ1 + θ2))

 

積で回転してしまう事が直感的に分かりにくいですが、簡単な式にiを掛けてみるとなんとなく理解できると思います。

(x + yi) ・ i

= xi + yi

= xi – y

= -y + xi

xとyが反転し、90度回転しています。

 

プログラムでは、以下のように積を表す事ができます。

シェーダ内でループ、関数が展開されてatan内でゼロ除算のエラーが出てしまうため、if文を挟んでいます。

 

マンデルブロ集合の公式

マンデルブロ集合 – Wikipediaを見ると、マンデルブロ集合は以下のように定義されています。

次の漸化式

  • zk+1 = zk2 + C
  • z0 = 0

で定義される複素数列{zn}nNn → ∞ の極限で無限大に発散しないという条件を満たす複素数 C 全体が作る集合がマンデルブロ集合である。

 

この式で出てくるzCは複素数です。

複素数C全体が作る集合として定義されているので、Cはレンダリングしようとしているピクセルの座標になります。

複素数zの初期値を0 = 0 + 0iとして、二乗してCを足すことを繰り返し、値が発散しない(値が大きくなっていかない)点の集合がマンデルブロ集合であることが分かります。

 

プログラムに起こすと、以下のようになります。

_MaxIterationはzk+1 = zk2 + Cを繰り返す数、_Thresholdは発散しているかを調べるための閾値です。

 

完成

以上を踏まえて作成したシェーダが以下のものになります。

 

おまけ

zk+1 = zk2 + C

Cを固定し、zの初期値をUV座標にすることで、ジュリア集合になります。

無題

 

 

Pocket

Pingbacks/Trackbacks

  1. [Unity]ジュリア集合で遊ぶ | notargs.com - 2015年11月7日

    […] 前回の記事を発展させて、様々なジュリア集合を描けるようにしてみました。 […]

  2. shader初心者が、notargs.comを見てマンデルブロ集合を書けるようになるまで頑張ってみた。 – TAKOYAKI (山神廉弥のブログ) - 2016年5月5日

    […] [Unity]マンデルブロ集合/ジュリア集合を描くシェーダを作る | notargs.com […]

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

(Required)

Proudly powered by WordPress   Premium Style Theme by www.gopiplus.com