【The 'Edge' of Inifinity】OpenGL 制作 Mandelbulb

大家好,本篇文章將會(huì)向你介紹如何使用 OpenGL 制作三維分形 Mandelbulb。

效果預(yù)覽



制作之前的準(zhǔn)備
因?yàn)楸疚氖腔?OpenGL 進(jìn)行制作的,所以讀者在進(jìn)行制作之前需要了解一些?C++ 程序設(shè)計(jì)語言和現(xiàn)代 OpenGL 編程規(guī)范。讀者可以在下面的網(wǎng)站學(xué)習(xí) OpenGL:
https://learnopengl.com/Getting-started/OpenGL
然而,這些工作并不是必須的。制作 Mandelbulb 還有很多更加方便快捷的方法,比方說使用三維軟件。在 Arnold 提供給 Maya 用戶的用戶手冊(cè)中就提供了這一例子,使用 Arnold 官方提供的方法你可以得到更好的效果。讀者可以在下面的地址中找到用 Maya 制作的方法:
https://docs.arnoldrenderer.com/display/A5AFMUG/How+to+Render+a+Mandelbulb
另外,還有專門的分形制作軟件 Mandelbulb3D,讀者只需要根據(jù)自己的喜好調(diào)整參數(shù)就可以了,這是最方便的方法。該軟件網(wǎng)站:https://www.mandelbulb.com/

關(guān)于 Mandelbulb
如果你對(duì) Mandelbrot 和 Mandelbulb 的歷史背景感興趣或者想有更加深入的了解,請(qǐng)參閱:
https://www.skytopia.com/project/fractal/mandelbulb.html#background
筆者只會(huì)對(duì) Mandelbulb 進(jìn)行一個(gè)淺顯易懂的簡單闡釋。
讓我們從稍微簡單一些的 Mandelbrot Set 開始解釋。你或許還記得數(shù)學(xué)上復(fù)數(shù)的概念,它就是基于復(fù)平面產(chǎn)生的,復(fù)平面上可以定義兩條互相垂直的軸,分別對(duì)應(yīng)復(fù)數(shù)的實(shí)部和虛部。為了觀測(cè) Mandelbrot Set,一個(gè)可行的辦法就是將復(fù)數(shù)的實(shí)部和虛部當(dāng)作二維坐標(biāo)來進(jìn)行計(jì)算。
這時(shí)候就可以引入我們的迭代公式了:
如何理解這個(gè)式子呢?讓我們從最簡單 z = 0 的開始,c 是一個(gè)復(fù)數(shù)參數(shù),那么
......
不同的復(fù)數(shù)參數(shù) c 可能使得這個(gè)序列發(fā)散到無窮,也可能收斂到有限的區(qū)域內(nèi),我們的任務(wù)就是找到能夠使得序列收斂的復(fù)數(shù) c 的集合,然后將其畫下來就可以了。這就是這個(gè)號(hào)稱 "上帝的指紋"的神奇圖形的本質(zhì)。
了解了 Mandelbrot,Mandelbulb 也是同樣的原理,只是 Mandelbulb 是三維的,我們需要為我們的二維坐標(biāo)增添一個(gè)維度,使用所謂的“ Triplex Number”,好在這在程序設(shè)計(jì)語言中很容易實(shí)現(xiàn)。
這時(shí),我們的迭代公式也產(chǎn)生了一些微小的變化:
不過這并不可怕,因?yàn)樵趯?shí)際編碼的過程中,我們可以自行設(shè)定 n 的值來產(chǎn)生不同的視覺效果,這賦予了我們更高的自由度。
不得不說的是, 在計(jì)算三維的 Mandelbulb 過程中,采用的三維矢量公式是在球坐標(biāo)系下的而不是直角坐標(biāo)系下的,這是由于不存在復(fù)數(shù)二維空間的三維模擬。關(guān)于球坐標(biāo)系下的公式,讀者可以參閱:
https://www.skytopia.com/project/fractal/2mandelbulb.html
上面詳盡記載了公式,還提出了一些提高效率的方法,相信比起我的粗糙解釋更讓人清楚和信服。

偽代碼

完整代碼
完整的代碼中添加了一些有用的 OpenGL 特性,還有可以自由操控的攝像機(jī),可以方便觀察,你可以在這里找到它:
https://github.com/Zwei-Reverberate/Generate-Mandelb

本文到此結(jié)束啦,感謝你的閱讀

