learn GLSL from zero
ToolsCreate with shadersShader MakerFree online shader builderToolkitShader works ready for your siteSketcher LabPaint your landing’s hero with shaders3D StudioThe Three.js editor in your browser
GamesPlay with shadersOnomatoShaderType a word, blow it upThe WatcherAn eye that follows youAetherLiquid glass with an eye insideBloomcoreA word grows a garden of lightPyrokineThrow fire at the wallVoltaicThe pyramid throws lightningSurfSurf a shader ocean

Lesson 3 of 10 · Fractals in GLSL

Escape

Do you stay or fly to infinity? Count the steps.

This is where the Mandelbrot set is born. For each frag we iterate z = z² + c and watch one thing: if z drifts past radius 2, it never returns, it escaped. We cut the loop and store which step it escaped on.

The set (those who never escape) stays black. The rest are painted by how fast they fled: slow escape near the edge = bright; instant escape far away = nearly black. Pure black and white, by iteration count.

if(dot(z,z) > 4.0) break;dot(z,z) is |z|², cheaper than a square root. 4.0 is radius 2 squared, the classic Mandelbrot escape threshold. Crossing it is the verdict: this frag heads to infinity.
TryChange dot(z,z)>4.0 to 16.0 and the halo fattens up. Move zoom to 0.8 to step into the edge detail.

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=120;
  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)>4.0){ n=float(i); esc=true; break; }
  }
  float g=n/float(IT);
  float shade=pow(g,0.45);
  vec3 col=esc ? vec3(shade) : vec3(0.0);
  gl_FragColor=vec4(col,1.0);
}
close