Exploring Indra’s Pearls with WebGPU

Nicolas Belmonte
6 min readApr 20, 2024

--

I’m excited to be releasing an interactive visualization using WebGPU of the fascinating math in the book “Indra’s Pearls: The Vision of Felix Klein” by David Mumford, Caroline Series and David Wright.

The book explores the patterns created by iterating conformal maps of the complex plane called Möbius transformations, and their connections with symmetry and self-similarity. These patterns were glimpsed by German mathematician Felix Klein, and modern computer graphics allows them to be fully visualized and explored in detail.

I’m writing this article as a companion to the interactive visualization. If WebGPU is not enabled in your device you can find a video here. If you want to learn more, please get the book!

Some Background

We start with a group of circles, which will be our seed elements. Our goal will be to cover / tessellate the entire plane, but unlike more “common” tessellations we will not directly use gyrations, (glide) reflections or translations.

Instead, we will be using Mobius transformations. We can think of these as a combination of translations, dilations, rotations, and circle inversions.

Given a group of four circles (the dark-red and dark-blue big ones in the exterior), the action of the Mobius transformation will take what’s outside of one circle and map it into the inside of the one in front of it.

Two iterations in, we see how the Mobius transformation has mapped the exterior of the outward circles into their respective interiors. The plane looks like a gruyere cheese!

The image above shows what this looks like after two iterations. The Mobius transformation has mapped the exterior of the outward circles into their respective interiors a couple of times. The result is a bit like a gruyere cheese: we covered “most” of the plane with the exception of the yellow/white interior circles.

If we iterate a few more times, we can make those “wholes” smaller, and if we do this at infinity we would have covered the entire plane.

Twenty iterations in.

Limit Sets

The book then explores Limit Sets: this is the set that is obtained by taking the intersection of all the circles in the group. For the picture above, this is “dust”, but for certain configurations we obtain more interesting shapes, introducing Fuchsian and Quasi-fuchsian groups.

Bringing the circles together generates closed curves as limit sets.

The Apollonian Gasket as a Limit Set

A special configuration of circles and generators (Mobius transformations) can generate the Apollonian Gasket as its limit set.

The limit set is the Apollonian Gasket

We show that some conjugations of the Apollonian Gasket can reveal other well known mathematical structures like Ford Circles. We also show that in this case, the conjugation can be thought of as the action of the rotation of a Riemann Sphere with a conformal mapping into the plane.

The Riemann Sphere rotates and reveals the Ford circles as it’s projected into the plane.

Generalizing Limit Sets: Beyond Circles

Instead of carefully selecting circles and Mobius transformations mapping the outside of one into the inside of another, we can generalize the work by directly computing limit sets from the Mobius generators themselves. This yields limit sets that are not necessarily built from circles.

Playing with parameters to get different limit sets

A parametrization of Mobius transformations that can give these “cusped” limit sets is known as the Maskit parametrization. A Maskit slice is the area under which the groups become non discrete (and we render nonsense).

µ values (x=Re(µ), y=Im(µ)) and the Maskit slice.

If we stay at the exact boundary, we get to groups that are at the limit of non-discreetness. The visualization allows to explore these cusped groups. The book goes into detail on the properties of these groups.

Moving through the boundary of the Maskit slice

Implementation

I used this project to get immersed into WebGPU and WGSL for shading programming.

The initial visualizations are created via a KleinGroup class. The class renders each iteration into a texture that is fed back into the class for an ulterior iteration. Programmatically, this mimics well the action of the Mobius transformations. The resulting texture is fed into a Quad class which renders the quad to the screen.

We then include an RSphere class which will render the Riemann Sphere. KleinGroup feeds the texture both to Quad and RSphere. The quad is then moved around with the sphere placed on top to describe how conjugations work.

Animation showing the RSphere and Quad classes in action.

Limit Sets

To visualize Limit Sets we implement Jos Ley’s: A fast algorithm for limit sets of Kleinian groups with the Maskit parametrisation. The algorithm renders a limit set via a fragment shader directly. The inputs to the fragment shader are the Mobius transformations and a texture that describes well the division across each side of the set. For each point in the screen if it falls in the area under or over the curve, we apply the Mobius transformation aor its inverse A.

The limit set and the underlying texture.

For sets far enough from the Maskit boundary, the line can be implemented as a smooth curve.

Cusps

For Limit Sets that are at the boundary of a Maskit slice this is more complex. We need to find the combination of Mobius products for which the group is parabolic (we call this the parabolic “word”). For each two Mobius transformations and their inverses, a, A, b, B, the word for it to be parabolic could be something like: aaaaBaaaaB. Finding the fixed point for this matrix product gives us a point that is tangent to two circles in the set.

We then need to cycle through these words in order to obtain all other fixed points that will be tangent to each circle in the set. My implementation to get the word and its cyclic permutations can be found in this notebook.

Texture computed for a cusped group at the boundary of a Maskit slice.

The texture above is using green and blue colors to indicate the algorithm to perform a horizontal shift before evaluating and applying the Mobius transformations (this gave me quite a headache).

Computing the Maskit Slice

Finally, to trace the Maskit Boundary we need to implement a Newton solver for parabolic generators (where the Trace=2). We walk the x-axis by obtaining a Farey sequence of fractions, for each of them we generate a Trace polygon, and we solve for it using Newton’s method, which will find the µ-value we need. Then the cusped limit set is fed the numerator of the Farey sequence p, its denominator q, and the complex value µ.

Limit sets for Farey sequences 0/5, 1/5, 2/5, 3/5, 4/5, 5/5

I hope you enjoyed this project and if you’d like to learn more, please get the book which goes in a lot more detail on many of these topics!

--

--

Nicolas Belmonte

Interested in Computational Design and Generative / Math Art.