Shader "Explorer/Mandelbrot" { Properties { _MainTex ("Texture", 2D) = "white" {} // first two numbers are center of area, second two - size of area _Area("Area", vector) = (0, 0, 4 ,4) _Angle("Angle", range(-3.1415, 3.1415)) = 0 _MaxIter("Max Iterations", range(0, 555)) = 255 _Speed("Speed", range(0, 1)) = 0.1 _EscapeRadius("EscapeRadius", range(2, 2000)) = 255 _SpectrumTexture("SpectrumTexture", 2D) = "white" {} _SpectrumSize("SpectrumSize", float) = 16 _ThemeTexture("ThemeTexture", 2D) = "white" {} _ThemeSize("ThemeSize", float) = 16 } SubShader { // No culling or depth Cull Off ZWrite Off ZTest Always Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = v.uv; return o; } float4 _Area; int _MaxIter; float _EscapeRadius; float _Speed; sampler2D _SpectrumTexture; int _SpectrumSize; sampler2D _ThemeTexture; int _ThemeSize; sampler2D _MainTex; fixed4 frag (v2f i) : SV_Target { // drawing stuff float2 uv = i.uv - 0.5; float2 offset = _Area.xy + uv * _Area.zw; // cool modulation float sub = tex2D(_SpectrumTexture, 0.0); float bass = tex2D(_SpectrumTexture, 0.25); float mids = tex2D(_SpectrumTexture, 0.50); float highs = tex2D(_SpectrumTexture, 0.75); float r = lerp(2.0, 200, bass); float maxIterations = lerp(2.0, 500, sub); // fractal bits float r2 = r*r; float2 c = _Area.xy + uv * _Area.zw; float2 z = 0; float2 zNext; int iter; for (iter = 0; iter < maxIterations; iter ++) { // f(z) = z^2 + c zNext.x = z.x * z.x - z.y * z.y + c.x; zNext.y = 2 * z.x * z.y + c.y; z = zNext; // unbounded if (length(zNext) > r) break; } // in the set // make it white if (iter >= maxIterations) { return 0; return 1; } float val = iter / float(maxIterations); float4 col = tex2D(_ThemeTexture, float2(sub, 1.0)); return col * val; // return float4(val, val, val, 1.0); // return tex2D(_ThemeTexture, highs); // float col = tex2D(_ThemeTexture, float2(highs * val, 1.0)); // return col; // from spinny curvy brot // float dist = length(z); // distance from origin // float fracIter = (dist - r) / (r2 - r); // linear interpolation // fracIter = log2(log(dist) / log(r) ); // double exponential interpolation // iter -= fracIter; // float m = sqrt(iter / _MaxIter); // float4 col = sin(float4(.3, .45, .65, 1) * m * 20)*.5 + .5; // procedural colors // col = tex2D(_MainTex, float2(m * _Repeat + _Time.y*_Speed, _Color)); // col *= smoothstep(3, 0, fracIter); // float angle = atan2(z.x, z.y); // col *= 1 + sin(angle*2 + _Time.y*4)*.2; // return col; } ENDCG } } }