Iso Holes
An alternative approach to faster holes is to use an isosurface.

Isosurfaces can often be slower than CSG, but in this case the CSG is so slow that
an isosurface can be considerably faster. This image took 4 minutes 14 seconds to render on my machine.
Because the isosurface is a single object,
the speed doesn't change very much when the number of holes becomes large.
Here's the complete code that I used for the above image
#include "functions.inc"
#declare D=35; // controls the density of the holes
// larger value gives more holes
#declare S = 0.1; // Controls the size of the holes
// larger value gives smaller holes
#declare R1=2; // Radius of outer cylinder
#declare R2=1.6; // Radius of inner cylinder
#declare H=4; // Height of the cylinder
isosurface {
function {
max ( // intersection
(f_leopard(D*R1*f_th(x,y,z),0,D*y) -S), // of the holes
max ( // with intersection
(x*x + z*z - R1*R1), // the of outer cylinder
(-x*x - z*z + R2*R2) // with the inner cylinder inverted
)
)
}
max_gradient 10
contained_by{box {-<R1,H/2,R1>,<R1,H/2,R1>}}
pigment {rgb .9}
finish {phong 0.5 phong_size 10}
}
camera { location <-8, 4, 0> look_at <0, 0, 0> angle 35}
sky_sphere { pigment {
function{abs(y)}
color_map { [0.0 color blue 0.6] [1.0 color rgb 1] }
}
}
light_source { <-20,50,-5> colour rgb 1}
Step by step
I started with a leopard pattern f_leopard(x,y,z). That gives a pattern
of spheres in 3d space. I then substituted 0 for the z parameter f_leopard(x,y,0)
which stretches the spheres out in the z direction so that they become cylinders.

The next job was to wrap the cylinders around the y axis, so that they radiate outwards.
I achieved this by substituting longitude (Theta) for the x parameter f_leopard(f_th(x,y,z),y,0).
Then, by making the function negative, I turned it into a set of cylindrical holes.

It's possible to perform intersection and difference operations of this isosurface with
CSG cylinders, like this
intersection {
isosurface {
function {
f_leopard(D*2*f_th(x,y,z),D*y,0) - 0.1
}
max_gradient 10
contained_by{box {-<2,2,2>,<2,2,2>}}
max_trace 6
}
difference {
cylinder {<0,-2,0>,<0,2,0>,2}
cylinder {<0,-2.1,0>,<0,2.1,0>,1.6}
}
}
But this requires the application of the max_trace feature, which
reduces the speed. So I then used the max operation to perform the
intersection and difference operations.
The first of the next pair of images was created with CSG cylinder differences with
max_trace 6 which turns out to be not quite enough, and there's
some drop out on the far side. The second image of the pair was created with
isosurface max operations and ran about three times faster.

Variations
Instead of the leopard pattern, I could have used any repeating pattern,
such as f_hexagon or created my own repeating pattern using repeat warps.
The boxed pattern with repeat warps needs a much higher max_gradient
and runs rather slowly.

For the spheres, the y parameter was replaced by the lattitude, Phi f_ph()
To have lines of holes tilted at a different angle I could substitute cos(A)*x +sin(A)*z
for x and cos(A)*z -sin(A)*x for z. When combined
with the other substitutions, that comes out like
f_leopard(D*(R1*f_th(x,y,z)*cos(A)+y*sin(A)),
0,
D*(y*cos(A)-R1*f_th(x,y,z)*sin(A)))

Isosurfaces
If you're not familiar with some of the isosurface techniques used here, then
you can find out more in my
Isosurface Tutorial.
Other Tricks
Holes Tutorial Part 1
Holes Tutorial Part 3: Transparent Holes (Bubbles)
Holes Tutorial Part 4: Blob-Holes
Back to Mike's Homepage
|