For the past several years I have been spending much more time using Adobe Photoshop than I have spent programming. This has left me feeling soft. Have I lost my technical edge and turned into a mere button-clicker? ”No” I tell myself. A Photoshop document is practically a program. Pixels are numbers. Layer groups are subroutines. Clipping mask are functional composition. Blending modes are mathematical operations. Channel mixers are matrices!
Am I deceiving myself into thinking that Photoshop is as close to programming as you can get without worrying about the halting problem?
I propose a challenge. Can we create a Photoshop document that renders the Mandelbrot set fractal? No scripts or plug-ins, just the standard photoshop adjustment layers.
We are going to start by deciding to make our document a 16bit CMYK image. The 16 bit mode gives about 100 times more precision than 8 bit, and the CMYK mode gives us an extra channel to use for temporary values. (Photoshop trivia: 16 bit mode is really closer to 15 bits — values go from 0 to 32768)
All operations in Photoshop use values between 0.0 and 1.0 while it is necessary to use numbers between -2 and 2 to calculate the Mandelbrot set. -2 becomes 0, 0 becomes .5, and 2 becomes 1.0. We are going to have to keep track of this mapping our selves. Depending on your preferences and color mode Photoshop may display values as 0%-100% or 0-255, but from a mathematical perspective it is better to always think of the values going from 0 to 1.0.
Since layers have no concept of their x,y positions in the image we will have to provide a coordinate system for them. We will use the Y and K channels for this. Y will be the x coordinate going from -2 (0.0) on the left to 2 (1.0) on the right. Similarly K will go from -2 at the top to 2 at the bottom. The gradient tool is not suitable for creating this base image as it does it’s interpolation non-linearly. I suggest creating a 2×2 pixel image and scaling it up to twice the final size with bilinear interpolation to get a linear coordinate system.
new_M = 2*C*M + K
new_C = C*C - M*M + Y
This doesn’t look too complicated, but photoshop has no simple way of performing signed multiplication. This means that we are going to have to invent a way to do it ourselves.
Lets say you have numbers stored in the cyan and magenta channels using the -2 to 2 mapping that you would like to multiply together. These are the steps you would take:
- Set the C and M channels to their respective absolute values. (an invert layer with the blend mode set to darken affecting only C and M)
- Scale the C and M channels so that our 0-2 range maps to photoshop’s 0-1 range. (A channel mixer with C=200C -100, M=200M -100)
- Overlay the M into the C channel. (channel mixer with C=100M, blendmode = overlay, affecting C only)
- Copy the C channel into the K channel and compress the range into .5-1.0. (channel mixer with K = 50C + 50)
- Discard the changes to all channels but K (Put all the previous layers in a layer group and set it to only affect the K channel)
- K is now equal to the absolute value of (C*M)/2
- If the cyan channel is < .5 then invert the black channel (invert layer with blending options set to blend if underlying cyan channel is > 127 affecting only K)
- If the magenta channel is < .5 then invert the black channel (invert layer with blending options set to blend if underlying magenta channel is > 127 affecting only K)
- K is now equal to C*M/2.
That algorithm reminds me more of assembly language than anything else. That satisfies my technical cravings.
There are a few more tricks to rendering the Mandelbrot set, but it is probably easier to understand by looking at the .psd file instead of reading about it.
Download rastered_mandelbrot.psb (.8MB)
If you would like to take the “Mandelbrot Challenge” yourself I recommend starting out with the Julia Set.
If you would like to learn more about the Mandelbrot set and complex math in general I highly recommend you read this article at acko.net. It is really beautifully done.
Other interesting facts:
- I designed this Mandelbrot renderer to perform interior shading, but it is possible to create a photoshop renderer with the traditional exterior shading, or even both at the same time.
- I have tested the file with Adobe Photoshop CS3. I don’t have a copy of Photoshop CS1 handy, but it should be capable of rendering the Mandelbrot set.
- It is not currently possible to do this with the Gimp, or Pixelmator (at least as a layered renderer).
If you liked this article you might also be interested in Playing Conway’s game of Life with Photoshop .