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 _Colors("Colors", vector) = (0.5, 0.5, 0.5, 0.0) _EscapeRadius("EscapeRadius", range(2, 2000)) = 255 } 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; float _Angle; float3 _Colors; // float _Speed; int _MaxIter; float _EscapeRadius; sampler2D _MainTex; fixed4 frag (v2f i) : SV_Target { float2 uv = i.uv - 0.5; float2 offset = _Area.xy + uv * _Area.zw; float r = _EscapeRadius; float r2 = r*r; float2 c = _Area.xy + uv * _Area.zw; float2 z = 0; float2 zNext; int iter; for (iter = 0; iter < _MaxIter; 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; // Bounded? if (distance(z, float2(0,0)) > r) break; } float val = iter / float(_MaxIter); return float4(val, val, val, 1); return float4(sin(val), sin(val), sin(val), 1); // 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 } } }