/*
kIFSe.pov
2010 Samuel Benge
With this scene file you can explore the world of Kaleidoscopic IFS fractals. These objects
will produce fractal detail at any level, provided you adjust the settings to account for the
finer details.
It renders a single isosurface with fast cavity shading. There are a number of settings to
change, but feel free to alter the core routines too. Scene settings (camera, lights, act.)
are at the bottom of the file.
Have fun!
__________
Parameters
ŻŻŻŻŻŻŻŻŻŻ
Symmetry
ŻŻŻŻŻŻŻŻ
The reflection set to use. It is possible to expand the symmetry set array to include
your own reflection planes.
Available symmetry sets:
0 = tetrahedral
1 = cubic
2 = octahedral
3 = icosahedral
COS
ŻŻŻ
Center of scaling. Change this for different polyhedra depending on the symmetry set.
tetrahedral symmetry
COS: <1,1,1> = tetrahedron
COS: <0,1,0> = octahedron
COS: <.5,1,.5> = truncated tetrahedron
cubic symmetry
COS: <1,1,1> = cube
octahedral symmetry
COS: <1,1,1> = cube
COS: <0,1,0> = octahedron
COS: <.5,.5,0> = truncated octahedron
COS: <.5,1,.5> = truncated octahedron with cut edges
icosahedral symmetry (Phi is predefined)
COS: <1,Phi,0> = icosahedron
COS: <1,1,1> = dodecahedron
COS: Lerp(<1,Phi,0>, , 1/3) = soccer ball (truncated icosahedron)
COS: Lerp(<1,Phi,0> ,<1,1,1>, .5) = truncated icosahedron with cut edges and dodecahedral tendencies
Scale
ŻŻŻŻŻ
This is the amount of scaling per-iteration. You can turn, say, an octahedron into an octahedral
Sierpinki's Gasket by changing this. Common values: 1.5 = polyhedra, 2 = Sierpinski's Gaskets
(not just for infinite improbability drives anymore)
Iters
ŻŻŻŻŻ
Number of iterations. Try to keep it above 20.
Substance
ŻŻŻŻŻŻŻŻŻ
This value will be subtracted from the isosurface function to give the shape substance,
and will also determine how fine to make the detail. Lower substance values will produce
more detail, higher values will make a simpler object. If you want to render deep zooms,
make this value *very* small, with a low accuracy value for the isosurface.
Default: 0.001
Accuracy
ŻŻŻŻŻŻŻŻ
This is just a shortcut to the isosurface's accuracy. It's best to have it around Substance/10.
Max_Gradient
ŻŻŻŻŻŻŻŻŻŻŻŻ
A shortcut to the isosurface's max_gradient. Usually a value between 0.5 - 1.0 will suffice,
but you should check the message pane after a test render to find the correct value to use.
Coloring_Mult
ŻŻŻŻŻŻŻŻŻŻŻŻŻ
This will affect the cavity shader used to color the object. It will need to be adjusted after
changing other settings. It is very sensitive to the number of iterations. Make sure to settle
on a good iteration value before making many changes to the other settings. Coloring_Mult will
need to be tweaked to get the right coloring. The cavity shader is far from perfect, so if you
make any useful changes, let me know!
Pre_Transform() & Post_Transform()
ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
These macros can be used to transform the object before and after the symmetry planes are
applied. This is one good way to get the most out of Kaleidoscopic IFS fractals.
Make_Container()
ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
You can change the isosurface's containing object with this macro. A default Container_Center is
provided, though how well it works has yet to be determined. It's best to center the object _after_
it is textured (example provided). Some objects may need a box container.
Do_Stuff()
ŻŻŻŻŻŻŻŻŻŻ
This macro will be called directly inside the isosurface object's definition after Make_Container()
has been called. With it you can texture the object, do transforms, or whatever.
____
Tips
ŻŻŻŻ
Keep the center of scaling in the "plus" range. (eg. COS = <1,1,1>)
If you're unsure of what kind of containing object to use, start off with a large box:
contained_by{
box{-2,2}
}
If the cavity shader produces lots of weird banding, try lowering the Accuracy value.
To preview the shader, add this after the cavity shading in the Do_Stuff() macro:
finish{ambient 1 diffuse 0} no_shadow
Some transforms will not work well at all. Rotations and translations are best.
Adding new reflection planes for non-uniform symmetries will require additional code. The center
of the reflection planes needs to be accounted for.
_______
Contact
ŻŻŻŻŻŻŻ
Decode the following, because I hate spam:
gestneb@hotmail.com
3472516@hotmail.com
*/
// Helful items for editing parameters
#macro Lerp(a,b,c) a*(1-c)+b*c #end // linear interpolation between two values
#declare Phi = (1+sqrt(5))/2; // The Golden Ratio (used for icosahedral symmetries)
//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ//
// editable parameters //
//_________________________//
#declare Symmetry = 3;
#declare COS = <1,Phi,0>;
#declare Scale = 2;
#declare Iters = 40;
#declare Substance = 0.001;
#declare Accuracy = Substance/10; // might never need to be changed
#declare Max_Gradient = 1.0;
#declare Coloring_Mult = 6.1;
#macro Pre_Transform()
//rotate y*3
#end
#macro Post_Transform()
//translate y*.2
#end
#macro Make_Container()
#declare Container_Center = COS/2; // this seems to work OK for most configurations
#declare Container_Radius = 1.5; // change radius as needed
contained_by{
sphere{Container_Center, Container_Radius}
}
#end
#macro Do_Stuff()
pigment{
pigment_pattern{ // cavity shading
function{Kaleidoscopic_IFS(Iters, true)}
color_map{[0 rgb 1][1 rgb 0]}
}
poly_wave 4 // adjusting the falloff
color_map{[0 rgb<0,.035,.1>][.55 rgb<1,.9,.6>]}
}
//finish{ambient 1 diffuse 0} no_shadow // uncomment this for fast preview
translate -Container_Center // centering the object
scale 2.5
rotate y*22
#end
//ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ//
// end editable parameters //
//_________________________//
// Expand this array to add new symmetry sets
#declare Symmetry_Planes =
array[4]{
// 0 = tetrahedral
array[6]{
x+z, y+z, -x+y, x-z, x+y, y-z
}
// 1 = cubic
array[3]{
x, y, z
}
// 2 = octahedral
array[6]{
-x+y, y-z, x-y, x, y, z
}
// 3 = icosahedral
array[9]{
vnormalize(<0,1,Phi>-),
vnormalize(-<0,1,Phi>),
vnormalize(<0,1,Phi>-<-1,Phi,0>),
z,
vnormalize(<1,Phi,0>-),
vnormalize(-<0,1,Phi>),
y,
x,
z
}
// Your reflection planes here
}
#declare CX = COS.x;
#declare CY = COS.y;
#declare CZ = COS.z;
// Copied from transforms.inc for speed
#macro VPerp_To_Vector(v0)
#if (vlength(v0) = 0)
#local vN = <0, 0, 0>;
#else
#local Dm = min(abs(v0.x), abs(v0.y), abs(v0.z));
#if (abs(v0.z) = Dm)
#local vN = vnormalize(vcross(v0, z));
#else
#if (abs(v0.y) = Dm)
#local vN = vnormalize(vcross(v0, y));
#else
#local vN = vnormalize(vcross(v0, x));
#end
#end
#end
vN
#end
#macro Shear_Trans(A, B, C)
transform {
matrix<
A.x, A.y, A.z,
B.x, B.y, B.z,
C.x, C.y, C.z,
0, 0, 0
>
}
#end
#macro Point_At_Trans(YAxis)
#local Y = vnormalize(YAxis);
#local X = VPerp_To_Vector(Y);
#local Z = vcross(X, Y);
Shear_Trans(X, Y, Z)
#end
// reflect a pigment from a plane (plane = vnormalize(from_pt - to_pt))
#macro Reflect_Plane(V_Plane)
transform{ Point_At_Trans(V_Plane) inverse }
warp{repeat y*1e7 flip y}
Point_At_Trans(V_Plane)
#end
// reflect all planes in a set
#macro Reflect_All_Planes(Plane_Set)
#local V=0;
#while(V*1e8;
#local rgb_sun = rgb<1.5,1.4,1.2>*1.3;
light_source{l_pos, rgb_sun }//area_light x*1e8,z*1e8,4,4 jitter}
light_source{<.3,.5,-1>*1e8,<.12,.12,.1> }//shadowless}// area_light x*1e8,z*1e8,2,2 jitter }
camera{
right x*2 up y*2
location -z*10+y*7
look_at 0
angle 30
}
sky_sphere{
pigment{
spherical scale 2 translate y
Point_At_Trans(l_pos)
cubic_wave
warp{turbulence .1 lambda 3}
pigment_map{
[0 rgb <0,.03,.15>]
[1 rgb_sun]
}
}
}
global_settings{
max_trace_level 2
#if(0) // relatively low radiosity settings which work well for high-accuracy objects
radiosity{
count 15 error_bound .1
pretrace_start .08 pretrace_end .04
nearest_count 1
recursion_limit 1
brightness 1
gray_threshold 0
adc_bailout 1/256
}
#end
}
//ŻŻŻŻŻŻŻŻŻŻŻ//
// end scene //
//___________//