In my previous articles I talked about the fundamental principles of Iterative Fractals, and the specific case of the Kaleidoscopic IFS fractal. Today we’ll extend the basic KIFS fractals beyond simple tetrahedral symmetry. Initially we’ll look at how to program iterative Menger 3D fractals, and 3D cube fractals. I’ll then show how you can mix these different types of fractal together to produce hybrid KIFS fractals.
Cubic Iterative Function
The cubic iterative function is a sequence of three folds which takes the +ve,+ve,+ve corner of a unit cube and replicates it symmetrically to all other corners. The code is relatively simple, and it’s possible to add a rotation in the same way that we did the the tetrahedron fold in the last article.
The code looks like this…
pos.Mul(matRot1); // pre-fold rotation pos[0] = abs(pos[0]); // all -ve = +ve pos[1] = abs(pos[1]); pos[2] = abs(pos[2]); pos.Mul(matRot2); // pos-fold rotation pos = pos*mScale - mPOffset; // scale + offset
To use this function inside wooscripter you’ll need to instantiate a distance object using the following shader.
shader cubeKIFS
{
diff = pos
repeat(15)
{
diff = kalcubestep(diff, vec(0,0,0), vec(0,0,0), vec(1,1,1), 2.2)
}
distance = box(diff, vec(1,1,1)) / pow(2.2, 15)
}
Note that with a default scale of 2 we simply get a cube. It’s necessary to change the scale to a higher value to start to see cracks in the cube faces. The following example uses a scale of 2.2
Menger Iterative Function
The menger iterative function is somewhat tougher to get your head round. Once again thanks to Knighty for first publishing this formula (I think). There’s a few steps to get this iteration to work. First let’s start by doing the .SetAbs(), this is equivalent to the cube step above. Now we’re going to fold three times to get space into a single quadrant on the Y axis. Next we offset the quadrant down 1/3, fold about the y axis, and return to the original position.
The code looks like this…
pos.Mul(matRot1);
float tmp;
pos.SetAbs();
if(pos[0]-pos[1]<0){tmp=pos[1];pos[1]=pos[0];pos[0]=tmp;}
if(pos[0]-pos[2]<0){tmp=pos[2];pos[2]=pos[0];pos[0]=tmp;}
if(pos[1]-pos[2]<0){tmp=pos[2];pos[2]=pos[1];pos[1]=tmp;}
pos[2]-=0.5f*mOffset[2]*(mScale-1)/mScale;
pos[2]=-abs(-pos[2]);
pos[2]+=0.5f*mOffset[2]*(mScale-1)/mScale;
pos.Mul(matRot2);
pos[0]=mScale*pos[0]-mOffset[0]*(mScale-1);
pos[1]=mScale*pos[1]-mOffset[1]*(mScale-1);
pos[2]=mScale*pos[2];
Note that this time round we need to use a default scale of 3 to see the standard menger cube. Once again it's possible to add a rotation into the fractal which gives some pretty results. But for now lets leave this with an identity matrix for the rotation. To check this out in wooscripter you'll need the following shader.
shader mengerKIFS
{
diff = pos
repeat(15)
{
diff = kalmengerstep(diff, vec(0,0,0), vec(0,0,0), vec(1,1,1), 3)
}
distance = box(diff, vec(1,1,1)) / pow(3, 15)
}
Hybrid KIFS systems
Now we have three different types of KIFS iteration step that we can use to build a hybrid. Let's start by mixing all three types in a single fractal. The shader is going to repeat only 5 times, but with 3 iterations in each loop.
shader hybridKIFS
{
diff = pos
repeat(5)
{
diff = kaltetrastep(diff, vec(0,0,0), vec(0,0,0), vec(1,1,1), 2.2)
diff = kalcubestep(diff, vec(0,0,0), vec(0,0,0), vec(1,1,1), 2)
diff = kalmengerstep(diff, vec(0,0,0), vec(0,0,0), vec(1,1,1), 3)
}
distance = box(diff, vec(1,1,1)) / (pow(3, 5) * pos(2, 5) * pos(2.2, 5))
}
This time we get a far more interesting result where the object shows some aspects of all of the individual fractals we've mixed together to generate this new hybrid.
If we consider just this simple set of iterations we can generate highly varied fractals by mixing different amounts of each iteration type in different orders. To show you how varied I rendered all 27 3-iteration variants of these fractals, the results are below.
A few of these are particularly pretty and worth a zoom. First up lets take a closer look at CTT (one cube iterarion followed by two tetrahedron iterations.
The MTC variant is also worth a closed look. This is a menger step, then a tetra, then a cubic iteration.
And of course, once you've got tired of doing the simple hybrids you can bring in some rotations and additional scalings and get all sorts of interesting images.
If you want to have a play with these fractals all the above functions are now supported in the latest version of Wooscripter. If you'd like to follow the progress of Wooscripter and learn more about fractals why not follow me on twitter @dom767.






