分形的奧秘!分形着色器!shader 編程入門實戰 ! Cocos Creator!
- 2020 年 4 月 9 日
- 筆記
極致的數學之美!文章底部獲取完整代碼!

什麼是分形?
「一個粗糙或零碎的幾何形狀,可以分成數個部分,且每一部分都(至少近似地)是整體縮小後的形狀」
簡單來說,分形(fractal)
就像這個doge表情包一樣,放大一部分後和原來的圖近似。

用分形着色器實現的效果如下,在編輯器內放大其中的一部分,會發現與整體非常相似!

如何實現這麼優雅的圖片?一切起源於簡單的公式(julia set)
。
f(n) = f(n-1) * f(n-1) + c
通過迭代 n
次後可以實現分形效果。
起始值 f(0)
如何確定?可以通過紋理坐標來確定。
當然這個起始值是個複數,有實數部分和虛數部分。我們用紋理u
坐標表示實數,v
表示虛數部分。
紋理坐標的取值是0-1
,可以加一些偏移和縮放處理。
float real = (v_uv0.x-0.5)/zoom + offset.x; float image = (v_uv0.y-0.5)/zoom + offset.y;
c
也是複數,對於不同的值,效果也不一樣。

一次迭代如何計算?記得虛數部分 i*i = -1
就可以根據公式計算了,參考代碼如下:
float tmp_real = real; // 計算新的複數-實數部分 // f(n+1) = f(n)*f(n) + c // (a+bi)*(a+bi) + c = a*a - b*b + (2*a*b)i + c_real + (c_image)i real = (tmp_real*tmp_real) - (image*image) + c_real; // 虛數部分 image = 2.0*tmp_real*image + c_image;
如何顯示不同的顏色?當迭代到一定次數後,這個迭代函數會發散。當這個複數的模大於2
時,停止迭代,並根據次數顯示不同的顏色。
for(float i = 0.0; i < 9999.0; i++){ // 計算新的複數... 省略部分代碼 // 複數大小的平方 r2 = real*real + image*image; conut = i; if(r2 >= 4.0){ break; } } if(r2 < 4.0){ o = v_color; }else{ o = vec4(mix(outColor1.rgb, outColor2.rgb, fract(conut*0.07)), 1); }
這裡用到了一些內置函數,不清楚的話可以看下圖。

如果我們對公式中的 c
修改一下,讓它與起始值相同,就變成了 mandelbrot set
。
float real = (v_uv0.x-0.5)/zoom + offset.x; float image = (v_uv0.y-0.5)/zoom + offset.y; float c_real = real; float c_image = image;
這幅圖被稱作上帝的指紋
。

以上為白玉無冰使用 Cocos Creator v2.2.2
開發"分形着色器"
的技術分享。有什麼想法歡迎留言交流!如果這篇對你有點幫助,歡迎分享給身邊的朋友。
原創不易!
本文使用圖片素材來自網絡!版權歸原作者所有,如有侵權還請聯繫!
完整代碼:https://github.com/baiyuwubing/cocos-creator-examples/tree/master/fractal