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

The complex plane

Every pixel is a number with two halves. Welcome to the map.

The whole route fits in one line: z = z² + c. Each pixel feeds its number to the rule and runs it again: square it, add c, repeat. If it blows up, it lands outside. If not, inside. The edge between the two is the fractal.

An escape fractal lives in the complex plane. Do not let the name scare you: it is the same plane you already know, except each point (x, y) is read as a single number z with two halves, real and imaginary. Here we map uv straight to z and paint it: ang drives the color, the radius rad pushes the tone.

Before iterating anything, you have to read the map. The two white lines are the axes: the crossing is the origin (0,0).

vec2 z = uv * zoomWe treat the frag as a complex number. z.x is the real part, z.y the imaginary one. zoom opens or closes how much plane fits on screen. Everything in the next 9 lessons does things to this z.
TryPush zoom to 2.5 to see more plane; drop it to 0.8 to lean into the origin. Move swirl from 2.0 to 5.0 and the color spins faster around the center.

The code

precision highp float;
void main(){
  vec2 uv=(gl_FragCoord.xy*2.0 - R)/R.y;
  float zoom=1.4;
  vec2 z=uv*zoom;
  float ang=atan(z.y,z.x);
  float rad=length(z);
  float swirl=2.0;
  vec3 col=0.5+0.5*cos(vec3(0.0,2.1,4.2)+ang+rad*swirl);
  col*=0.55+0.45*smoothstep(2.2,0.0,rad);
  float ax=smoothstep(0.02,0.0,abs(z.x))+smoothstep(0.02,0.0,abs(z.y));
  col+=vec3(1.0,0.95,0.85)*ax*0.55;
  gl_FragColor=vec4(col,1.0);
}
close