Basics of Ultra Fractal

For the Fractal Formulas blog, we will be using the program Ultra Fractal for two dimensional escape time fractals. It is commercial software (a free trial version is available) available at http://ultrafractal.com/. We’ll be focusing on the concepts and formulas here, not the mechanics of the user interface (Ultra Fractal comes with a set of tutorials to learn that). There is an extensive public formula database that contains most of the formulas that will be covered in this blog. Be sure to load it into your copy of Ultra Fractal by running Options->Update Public Formulas.

As we saw in Basic Fractal Concepts, escape time fractals are defined by iterating a formula on a set of points. Points that “escape” (usually by exceeding some threshold) are “outside” and points that don’t are “inside” the fractal. Let’s explore that in more detail.

Ultra Fractal represents points as complex numbers: the real part is the x coordinate and the imaginary part is the y coordinate. This allows the point that is iterated to be stored in a single variable, named z. (Don’t confuse this with the z coordinates present in three dimensional systems; Ultra Fractal only uses two dimensions.) An Ultra Fractal formula can either use z as a complex value (the language Ultra Fractal provides for writing formulas supports complex arithmetic and functions), or it can split the real and imaginary parts into x and y coordinates to compute the new value separately.

The above figure shows a representation of the formula $z_n=z_{n-1}^2-1.25$ (using the formula Julia). The inside points are black.The first few iterations of the orbits of two points, one inside (blue squares) and one outside (red diamonds) are shown. The green arrow shows the initial points, which are very close to each other so overlap in the drawing. The first points in the orbit are near the left edge, still very close to each other. The second points are the farthest points to the right, and are beginning to separate. Notice that the inside orbit points are always inside the figure and the outside orbit points are always outside the figure. The 14th point of the outside orbit is at the bottom right of the drawing, the 15th and all subsequent points are outside the drawing. Note that the lines connecting the points are to show the order, and are not part of the orbit.

Ultra Fractal uses the fractal formula to compute the orbit and determine if a point is inside or outside. A coloring algorithm is then used to compute what color the point should have. Since the orbits for inside and outside points behave very differently, separate inside and outside coloring algorithms are used. These algorithms are independent of the fractal formula, so can be used in different combinations to produce various effects. For example, the following fractal uses the same formula used to produce the stark black and white image above. Outside points are colored using Smooth (Mandelbrot), which uses the escape time modified by the final z value to smooth the result. This coloring won’t work for the inside since the orbit never escapes; the inside coloring is Lyapunov, which computes a mathematical construct called the Lyapunov exponent to color the inside points.

To understand the details of how Ultra Fractal works, let’s start with a much simpler formula called a Pixel formula, which just passes the point associated with a pixel to the coloring algorithm. There are several Pixel formulas available, with different properties. The one I use the most often is “Pixel (jp)” from jp.ufm, which generates an orbit with a single point for each pixel. Set Maximum Iterations to 1 to make all the points inside or to 2 to make them outside. It can be very useful for exploring coloring algorithms since it omits the complexity of fractal iterations.

Here are some parameters to copy and paste into Ultra Fractal so you can follow along, and the resulting image:

BasicPixel {
fractal:
title=”Basic Pixel” width=500 height=500 layers=1
layer:
caption=”Background” opacity=100 method=multipass
mapping:
center=0/0 magn=1
formula:
maxiter=1 percheck=off filename=”jp.ufm” entry=”pixeljp”
inside:
transfer=linear solid=4278222848 filename=”lkm3.ucl” entry=”basic-3″
p_vartype=z p_const=0/0 p_colorby=magnitude f_fofvar=ident
outside:
transfer=none solid=4286578688 filename=”lkm3.ucl” entry=”basic-3″
p_vartype=z p_const=0/0 p_colorby=magnitude f_fofvar=ident
smooth=yes index=0 color=0 index=200 color=16777215
opacity:
smooth=no index=0 opacity=255
}

To begin, we set Maximum iterations to 1 so that all the points will be inside. We’ll also use a simple coloring algorithm: “Basic 3” from lkm3.ucl, which provides a number of basic coloring options. The default is to color by iterations (i.e., the escape time), which isn’t useful for inside coloring or pixel formulas since the number of iterations is always the same. Instead, we’ll set the Basic 3 parameters to color z by magnitude. In a coloring algorithm, “z” is the final iteration value, which will be the point for the pixel itself since we are using a pixel formula. Magnitude is the distance of the point from the origin, which it at the center of this figure. So the coloring algorithm here computes the distance of each pixel from the center and uses that as an index to look up the result in the gradient.

The gradient we are using is the standard Grayscale gradient (you can see it by clicking the Gradient button in the toolbar), with black at position 0 and white at position 200 (color index 0.5). The color transitions smoothly from black to white and back to black as the index goes from 0.0 to 0.5 to 1.0, and works very well when Repeat Gradient is checked (as it is here) since the smooth transition repeats from 1.0 to 1.5 to 2.0 to 2.5, and so forth. We can see that in the image by starting at the center and going outward; it is white at 0.5 units away, black at 1.0 units, white at 1.5 units, etc. We’ll be using this gradient a lot in our explorations. It’s useful when there is no upper limit to the color index so we want to repeat the gradient.

Let’s try changing some parameters. To begin, on the Inside tab change “color by:” from “magnitude” to “real part”. Now, instead of calculating the distance from the center, the coloring algorithm just takes the real part of z, which is the x value. The y value (imaginary part) is ignored, so the value is the same for every y value, resulting in two vertical bars to the right of the center. Note that the image to the left of the center is black. This is where the x values are negative. Negative values for the gradient index will always use the gradient color for value 0, even if Repeat Gradient is checked. This is important to understand. If you have a fractal that has a lot of the zero gradient value, there is a good chance the coloring algorithm is producing negative values.

Some coloring algorithms prevent the gradient index from being negative. Others may provide a method to avoid it. For example, Basic 3 has an option to color by “f(real part)”, where the “f” means a function specified in the parameter “modifying function” that appears when you select that. If you change “color by” to “f(real part)” and “modifying function” to “abs” (for absolute value), the negative values will be forced positive, resulting in vertical bars to the left as well as the right of the center.

Now, try unchecking Repeat Gradient. The outside bars disappear. Going from the center to the right, the color is white at 0.5 and black at 1.0, but without repeating, the color remains black (the 1 value) when it gets larger than 1. The same thing happens going from the center to the left; the real part goes to -0.5 then -1.0 and so on, and the abs function makes the gradient index value positive.

Using color by “imag part” or “f(imag part)” works the same as real part except that the imaginary part of z or the y value is used, so the lines are horizontal instead of vertical. Another option for color by is “polar angle”, which is the angle between a line from the origin to the point and the positive x axis, adjusted to a value between 0 and 1. For example, a point on the y axis, straight up from the origin, has an angle of 90°, which is adjusted to 0.25. A point straight down would have a value of 0.75. The result is shown below on the left.

The Color Density value is the very first parameter for every coloring algorithm, and knowing how it works is important for controlling the coloring of fractals. To explore it, let’s go back to the original parameters shown above (color by magnitude with Repeat Gradient checked). The gradient index determined by the coloring algorithm is multiplied by the Color Density before the actual gradient lookup. So far, it has always been 1, so hasn’t changed the gradient index. But let’s change it to 3. Now, instead of two complete rings (plus part of a third at the corners) there are three times as many, or six complete rings (plus parts of three more at the corners), as shown in the middle figure below. Fractional values are allowed, so for example, a Color Density of 2.5 would show five complete rings and 0.5 would show one.

There is much more to learn from this simple combination of Pixel and Basic 3, but let’s explore just one more thing before going on to a real fractal. Again, go back to the original parameters above (just set Color Density to 1 if that’s all you changed) and uncheck Repeat Gradient to show a single ring. Now go to the Gradient window by clicking the Gradient button on the toolbar (if it is already showing, you can just click it). Click the control point for the white value; the Position should show “200”. Change the Position to 0. This converts the gradient from black-white-black to white-black, and changes the image from a ring to a shaded circle, shown in the right figure above. We’ll be using this gradient a lot too. It’s useful when we can determine an upper limit for the color index and don’t want to repeat the gradient.

Let’s apply what we’ve learned so far to a more complex formula, Julia. Using the same coloring as before, we just change the formula to Julia from Standard.ufm and increase the Maximum Iterations to 100.

Let’s see how this works with a more complex formula. We make three changes to the starting point given above:

• Change the formula to Julia from Standard.ufm. This is the same formula we used above to show the orbits of a couple of points. We’ll continue using the default values of the Julia parameters.
• Increase the Maximum Iterations to 1000. We obviously need more iterations than the 1 we used with Pixel (jp). The number 1000 is somewhat arbitrary, but it works well for the scale we are using. If we zoom in, we’ll need to increase Maximum Iterations to generate more detail.
• On the Inside color tab, increase the Color Density to 16. This helps to separate the colors (well, shades of gray here, but you can imagine how it would look if the gradient had colors).
• On the Outside color tab, the Transfer Function is None, which uses the Solid Color (which is red) for all outside points. This isn’t a change; this setting was in the parameters above, but we never used the outside coloring so haven’t seen it.

Here is a new set of parameters with these changes and the resulting image:

BasicJulia {
fractal:
title=”Basic Julia” width=500 height=500 layers=1
layer:
caption=”Background” opacity=100 method=multipass
mapping:
center=0/0 magn=1
formula:
maxiter=1000 percheck=off filename=”Standard.ufm” entry=”Julia”
p_seed=-1.25/0 p_power=2/0 p_bailout=4.0
inside:
density=16 transfer=linear solid=4278222848 filename=”lkm3.ucl”
entry=”basic-3″ p_vartype=z p_const=0/0 p_colorby=magnitude
f_fofvar=ident
outside:
transfer=none solid=4286578688 filename=”lkm3.ucl” entry=”basic-3″
p_vartype=z p_const=0/0 p_colorby=iterations f_fofvar=ident
smooth=yes index=0 color=0 index=200 color=16777215
opacity:
smooth=no index=0 opacity=255
}

The Julia formula, unlike Pixel (jp), divides points into inside and outside. To begin with, we just color the outside points red so we can focus on the inside. (We’ll get to the outside shortly.) The magnitude of the final orbit point (after 1000 iterations of the formula) is one of four values, indicated by the four different shades of gray in the figure. Interestingly, each of the points in each bulb of the fractal end with the same (or nearly the same) value. The structure of this fractal is fascinating, but we need to focus here on how Ultra Fractal works so we won’t go into it. What is important for our purposes is that there are clusters of bulbs colored alternately black and white, and other clusters of bulbs colored dark and light gray.

For inside points (like these), small changes in the Maximum Iterations value (on the Formula tab) can make a big difference. For example, if we change the Maximum Iterations value here from 1000 to 1001 the black/white and dark/light gray bulbs switch places. Changing to 1002 puts the original colors on the clusters, but reversed, and changing to 1003 switches places again (but reversed from 1001). Interestingly, using 1004 produces the same result as 1000, and the sequence repeats. This gives some insight to the orbits: the points for this fractal repeat with period 4. Other fractals will have different periods; for example, changing “Julia seed (Re)” from -1.25 to -1.375 results in a fractal with period 8. We won’t show that here, but feel free to explore it on your own.

Coloring by iterations is never interesting for inside coloring because the number of iterations is always the same (the Maximum Iterations value). For this fractal, the other color by options aren’t very interesting since the orbit points are all on the x axis. For example, color by f(real part) with function abs appears the same as magnitude. So let’s go on to explore outside coloring.

First, change the Inside coloring Transfer Function to None to color the inside points green (the Solid Color), then change the Outside coloring Transfer Function to Linear. The color by parameter is set to iterations, which divides the number of iterations by 100 and uses that as the color index. That might be a good value if we were zoomed in to part of the fractal where the number of iterations is higher.

But for the entire fractal most of the area is black because the number of iterations is mostly less than 10, so we are using the leftmost tenth of the gradient, which is pretty much black. We can’t change the divisor; it is fixed at 100. But there are some ways to work around it.

Rotating the gradient so that the left tenth has a more rapidly changing part will start to show the different iteration values. Explore different settings; rotating left will make it dark to light from outside to inside and rotating right will do the opposite. The image on the left below has a Rotation of -90. But there still isn’t too much contrast since we are only using part of the gradient. So let’s set the rotation back to 0 and try something else.

The gradient has 400 points, so one tenth of the gradient is at position 40. If we move the white point from position 200 to position 40, the part of the gradient we are using will have the maximum range from black to white; see the middle image below. Explore different values by dragging the white point back and forth to see the effect on the fractal coloring. Position 40 may have the highest overall contrast, but other values may have a more aesthetic effect. There is no “correct” value! When you are done exploring, set the white point position back to 200.

We can have more control over the results if we can coax the coloring algorithm to use a larger part of the gradient. We can’t change the factor of 100 that is fixed in the Basic 3 coloring, but we can achieve the same result by adjusting the Color Density value. Since we are currently using a tenth of the gradient, let’s set it to 10, which will scale the gradient index to use the entire gradient, as shown in the image on the right.

A large area outside the fractal is still black because the orbit escapes on the first iteration. We can adjust that with the Formula Bailout value. When the magnitude of an orbit point exceeds the bailout value, the orbit escapes and becomes an outside point. With the Julia formula, setting the Bailout value anything above 4.0 (the default) will not affect which points are inside vs outside. But it will make the orbits longer, and thus affect how they are colored. Let’s change the Bailout to 25.

Looking closely at the corners, we can see that there are small black areas. That is where the number of iterations is 0; at these points, the first application of the fractal formula ($z_n=z_{n-1}^2-1.25$) exceeds the Bailout value of 25. The top and bottom of the fractal are dark gray. These points have an iteration value of 1; the first application of the formula doesn’t exceed the bailout value, but the second value does. The next lighter color is an oval region where the iteration value is 2. Continuing inward are lighter regions with iteration values 3, 4, and 5. These regions are getting closer to the Julia fractal, so are starting to deform from an oval to match the Julia shape. Iteration value 5 maps to the middle of the gradient (the coloring algorithm divides 5 by 100, which is multiplied by the Color Density of 10, resulting in 0.5), so it is white. The regions going further in are much thinner; they get darker from 6 to 10, which is black.

It’s important to note here that there are definite boundaries to each region; it isn’t a smooth transition. This is because the number of iterations is always an integer. We can emphasize this effect by using only two colors, black and white with the gradient we are using. To do this, set the Color Density to 50. The coloring algorithm divides the number of iterations by 100 and the Color Density multiplies it by 50, resulting in a net division by 2. Odd iteration counts will be white and even ones will be black. The end result is a stark map of the iteration contours, as shown in the left figure below.

Some coloring algorithms are able to interpolate the values using the final z value to give the fractal a smooth appearance, as was done in the color picture above.

We can, of course, color by items other than the number of iterations. But the result will still follow the iteration contours. The middle figure below shows color by magnitude, with Color Density set to 1. It isn’t particularly pretty; coloring outside points by magnitude often shows the coincentric rings seen when using a Pixel formula, though they are distorted by the fractal formula. But there is an important lesson to learn from this figure. Note the gray circles at the top and bottom and elsewhere. They aren’t real! These phantom circles are moiré patterns, caused by trying to map the thin curved lines of the fractal to the square pixels of the figure. These patterns are difficult to control, so don’t count on them for effects or textures in your fractals. To avoid them, you can make the rings larger by decreasing the Color Density.

Finally, the figure on the right above shows the result of coloring by polar angle. It is a bit harsh by itself, but combining it on one layer with some other coloring on another can have interesting results, as shown below (with color and inside coloring added).

Behind the Scenes