Lesson 4 of 10 · Fractals in GLSL
Smoothing
The steps melt into a continuous gradient.
Last lesson the count is an integer: 7 steps, 8 steps, 9. That is why you see stepped rings. But the escape holds more info: by how much it overshot the threshold on the final step. With that we interpolate between steps.
The magic formula: n - log2(log2(|z|²)). It sounds heavy, but it just turns the discrete jump into a number with decimals. The rings become silk.
sn = n - log2(log2(dot(z,z))) + 4.0The smooth iteration count.
n is the integer escape step; the double log2 measures how far z flew as it crossed, filling the gap between one integer and the next. The +4.0 just re-seats the range.Raise the second number in
pow(g, 0.4) to 0.8 to darken the mids, or drop it to 0.2 to flatten the brightness. Push dot(z,z)>256.0 higher and the smoothing gets even cleaner.The code
precision highp float;
void main(){
vec2 uv=(gl_FragCoord.xy*2.0 - R)/R.y;
float zoom=1.5;
vec2 c=uv*zoom+vec2(-0.6,0.0);
vec2 z=vec2(0.0); float n=0.0; bool esc=false;
const int IT=140;
for(int i=0;i<IT;i++){
z=vec2(z.x*z.x-z.y*z.y, 2.0*z.x*z.y)+c;
if(dot(z,z)>256.0){ n=float(i); esc=true; break; }
}
float sn=esc ? (n - log2(log2(dot(z,z))) + 4.0) : 0.0;
float g=sn/float(IT);
float shade=pow(g, 0.4);
vec3 col=esc ? mix(vec3(0.03,0.04,0.09), vec3(0.95,0.98,1.0), shade) : vec3(0.01,0.01,0.03);
gl_FragColor=vec4(col,1.0);
}