• Recursively repeat spheres (and circles) along the x, y and z axis - at each recursion we scale and offset the sphere.
• Visualize the fractal as 2d in HTML canvas and in 3d using ray-tracing (WebGL and WebGPU)
• As the pattern is a fractal - the detail is limitless but also costly (from a few hundred to a few hundred thousand spheres depending how many recursions)
Simple 2D Example
Can you make a fractal from just spheres? Absolutely, and it's every bit as mesmerizing as you might imagine. Fractals are complex patterns that exhibit self-similarity, meaning they look the same at any scale.
The sphere fractal presented here works by by repeating a simple shape like a circle, but each time you repeat the shape, you make it smaller and place it in specific spots around the original. This keeps repeating creating a never-ending pattern that looks the same no matter how much you zoom in, and it all happens thanks to some nifty recursive math!
We implement a simple 2d version of this using a
circlefractal
function. The function calls itself (i.e., recursively) to add smaller and smaller cirles inside and outside the parent circle to create a mesmerizing layout.
The concept and code is very simple - but the results are very beautiful and mezmorizing.
Fractal as circles - 2d visualization.
The implementation is given below in JavaScript and HTML canvas.
The sphere fractal obeys the self-similarity rule of fractals - which means that no matter how much you zoom in on the pattern, you will find smaller versions of the same shape.
// Define the circle parameters var centerX = canvas.width / 2; var centerY = canvas.height / 2;
const ellipse = (centerX,centerY,radius) => { // Begin the path for the circle context.beginPath(); context.arc(centerX, centerY, radius*0.5, 0, 2 * Math.PI, false);
// Fill the circle with color context.fillStyle = "rgba(128,0,0,0.5)"; context.fill();
const circlefractal= (x,y,s) => { if ( s < 20 ) return;
ellipse(x,y,s);
/// smaller inside the main circle circlefractal(x + (s/3), y, s/3); circlefractal(x - (s/3), y, s/3); circlefractal(x, y+(s/3), s/3); circlefractal(x, y-(s/3), s/3);
// smaller outside the main circle circlefractal(x + (2*s/3), y, s/3); circlefractal(x - (2*s/3), y, s/3); circlefractal(x, y + (2*s/3), s/3); circlefractal(x, y - (2*s/3), s/3); }
circlefractal( 250, 250, 200 );
Ramp up the detail to further recursive depth and more spheres.
2d to 3d (circles to spheres)
When extended into 3D we'll extend the algorithm to include a `z-value` - which repeats in the same way as the x and y axis. For the 3d example, we'll use ray-tracing (WebGL and WebGPU). We can create the spheres in JavaScript and pass them through to the ray-tracer. We'll use fractals so we can add mirror effects!
Ray-traced the sphere fractal of different levels.
We've implemented the example in both WebGL and WebGPU. The spheres positions and radius are generate in JavaScript and passed across to the fragment shader for ray-tracing.
For the 3d version - we'll only show the spheres on the outside (not the inside ones as we did with the 2d version).
let spheres = []; const buildSphereFractal = (x,y,z,r) => { if ( r < 0.01 ) return;
spheres.push( { x, y, z, r:r*0.5 } );
// smaller outside the main circle buildSphereFractal(x + (2*r/3), y, z, r/3); buildSphereFractal(x - (2*r/3), y, z, r/3); buildSphereFractal(x, y + (2*r/3), z, r/3); buildSphereFractal(x, y - (2*r/3), z, r/3); buildSphereFractal(x, y, z + (2*r/3), r/3); buildSphereFractal(x, y, z - (2*r/3), r/3); } buildSphereFractal(0,0,0,1); console.log('num spheres:', spheres.length );
• WebGL - we pass the fractal spheres across using a
uniform
buffer.
• WebGPU - we pass the fractal spheres across using a
gpu
buffer.
The links for the interactive versions are given at the bottom. They're drawn using a classical ray-tracing algorithm with recursion for the reflective vector.
WebGPU Buffer
The WebGPU buffer is implemented as using the following code:
Visitor:
Copyright (c) 2002-2025 xbdev.net - All rights reserved.
Designated articles, tutorials and software are the property of their respective owners.