極致的數學之美!

什么是分形?
“一個粗糙或零碎的幾何形狀,可以分成數個部分,且每一部分都(至少近似地)是整體縮小后的形狀”
簡單來說,分形(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://www.uj5u.com/qita/3889.html
標籤:其他
上一篇:lua學習之深入函式第二篇
