極致的數學之美!編輯器
什麼是分形?函數
「一個粗糙或零碎的幾何形狀,能夠分紅數個部分,且每一部分都(至少近似地)是總體縮小後的形狀」3d
簡單來講,分形(fractal)
就像這個doge表情包同樣,放大一部分後和原來的圖近似。code
用分形着色器實現的效果以下,在編輯器內放大其中的一部分,會發現與總體很是類似!blog
如何實現這麼優雅的圖片?一切起源於簡單的公式(julia set)
。圖片
f(n) = f(n-1) * f(n-1) + c
經過迭代 n
次後能夠實現分形效果。開發
起始值 f(0)
如何肯定? 能夠經過紋理座標來肯定。數學
固然這個起始值是個複數,有實數部分和虛數部分。咱們用紋理u
座標表示實數,v
表示虛數部分。class
紋理座標的取值是0-1
,能夠加一些偏移和縮放處理。file
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
開發"分形着色器"
的技術分享。更多精彩內容在公衆號【白玉無冰】。有什麼想法歡迎留言交流!若是這篇對你有點幫助,歡迎分享給身邊的朋友。