It’s a bit cliche at this point to discuss how stimulating M. C. Escher’s “Print Gallery” is, and many others have done an incredible job at describing why in great depth. The punchline, however, is that the scene shows a man (bottom left) gazing into a picture at a print gallery, and within the picture’s frame is a scene of a town, and within that town is an art gallery, and within that art gallery is that same man looking into the picture. Unlike other “Droste Images,” however, where the picture containing itself has a smaller version of itself within itself, Print Gallery achieves self reference through this “strange loop.” That is, the swirling distortion you see as you navigate your eyes clockwards is illustrating that the man is within the very picture he is viewing without needing to repeat the image within itself.
I recently watched a math youtube video by 3Blue1Brown (as an aside, this is the most incredible math channel; if you’re every learning math, look him up) which dives into the math of the process Escher used in creating the image. Notably, Escher created his distortion entirely using intuition, but the punchline of the video was that Escher created a process that has an equivalent, relatively straightforward set of mathematical functions that can be used to achieve the same result.
So I set out to create a shader that illustrated this same effect except in an interactive way where you can click your mouse to tweak various parameters. Shaders, for those who don’t know, are tools that can create art from mathematics. To accomplish my goal, the first task was to create a procedural droste image. Rather than make an entire seaport, however, I created two very simple droste images.
1) A circle embedded within a circle embedded within a circle embedded… and so on, and
2) a grid embedded within a grid embedded… and so on.
What’s cool about shaders is they can be virtually infinite without sacrificing performance, so you can zoom in infinitely far without issue (at least up until you reach some type precision constraint)
Skipping over all the fun math, when you apply the same processes (math) that Escher used for creating Print Gallery on these simple Droste shaders, you get the following.
You can envision what this might mean with the following two diagrams. The first represents a classic droste image, one where the image is entirely within itself over and over again.

Each box might represent something in the image, like the bottom left box being the observer in the painting gallery, the top left the sky, the top right the city, the bottom right the gallery, and the inner bottom left being the observer again. Btw, this image is only zoomed in by a factor of 16, but Print Gallery is actually zoomed in by a factor of 256, meaning you’d have to zoom in much more for M. C. Eschers painting to see this same effect. But the point is that it is the same, and the math transforms these boxes as follows.

Notice this has the mind-bending property that each box retains their visual proportions in this new Escher-like image, but ALSO squeeze into fitting into one another. At least, that’s the least mathy way I can describe it lol. Put another way, if you move your eye opposite the arrows, each green box, containing 4 cells in this case, would “slide” into a single cell within the next green box… in a loop. They all fit into one another. How trippy!
The fun for me was primarily writing the shader, but here’s the last part I’ll leave you with. Because I control all of the math, I can do wild things, like increase the scale (below is escher’s ACTUAL scale of 256)
I can show “strange loop” embeddings other than square. Note that I’m still trying to understand how the number of “arms” relates to images embedded within themselves… I’ll color them and update the shader in a future post.
Anyway, most importantly, I can just drag my mouse around to see how these transforms look when you have full control over the math.
Notably, while I only show this for the grid and circles, this shader would work on any droste image.
Thanks for reading!
