分形的奧秘!分形着色器!shader 編程入門實戰 ! Cocos Creator!

極致的數學之美!文章底部獲取完整代碼!

什麼是分形?

「一個粗糙或零碎的幾何形狀,可以分成數個部分,且每一部分都(至少近似地)是整體縮小後的形狀」

簡單來說,分形(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