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 2 of 10 · Fractals in GLSL

z = z² + c

One rule, repeated. The seed of everything.

The whole Mandelbrot family is born from one line: z = z² + c. Squaring a complex number is not x²; it is (x²-y², 2xy), a rotation plus a stretch. That is the strange line inside the loop.

Here c is the frag and we start z = c, iterating just IT=5 times. We are not deciding who escapes yet; we paint the raw field, how big z got after a few steps. The silhouette is already peeking through.

z = vec2(z.x*z.x - z.y*z.y, 2.0*z.x*z.y) + cComplex multiplication: real part x²-y², imaginary part 2xy. Adding c re-injects the frag position each turn. Repeating this is the entire fractal.
TryChange const int IT=5 to 2 and the field is barely formed; WebGL needs a fixed loop count. Push zoom to 2.2 to open the frame.

The code

precision highp float;
void main(){
  vec2 uv=(gl_FragCoord.xy*2.0 - R)/R.y;
  float zoom=1.6;
  vec2 c=uv*zoom+vec2(-0.5,0.0);
  vec2 z=c;
  const int IT=5;
  for(int i=0;i<IT;i++){
    z=vec2(z.x*z.x-z.y*z.y, 2.0*z.x*z.y)+c;
  }
  float m=length(z);
  float tone=log(1.0+m);
  vec3 col=0.5+0.5*cos(vec3(0.0,2.3,4.6)+tone*3.0);
  col*=smoothstep(40.0,0.0,m)*0.8+0.12;
  gl_FragColor=vec4(col,1.0);
}
close