|
|
|
|
|
|
| |
| |
|
|
|
|
| |
| |
|
|
Since fractals seem to be the theme nowadays, here's my shot at it.
There's quite a developement history behind this image.
The basic idea was this: What if you take a julia fractal and then
extrude it (a bit like a prism), but while you extrude it, change
the complex number from which the julia is being calculated? That is,
different layers of the prism are composed of julia fractals with
slightly modified values.
Allright, so take the julia fractal for example for <0.353, 0.288>
and extrude it by half a unit so that at the other end it is the
julia for <0.353+0.25, 0.288>. 10 iterations should be ok.
How exactly to implement this was in no way trivial.
My first thought was to make an isosurface using the julia fractal
pattern as a function. So far so good, but pattern functions can't take
parameters, so it can't be done like that.
So I had to actually make the julia fractal function, in other words
a recursive function myself (it's slower, of course, but works).
I got the isosurface to work, but it had one problem: Not accurate
enough. The surface was full of noise. I had to lower the accuracy
by two orders of magnitude in order to get a smooth surface, but at
the cost of a ridiculously high max_gradient (over 20000). Not good.
So I settled on a compromise: accuracy 1e-4, max_gradient 2000.
It still had some noise, but not as much. Bearable.
However, it was still not good: After 1.5 hours of rendering the
final version and when only about 10% was ready (and it was only
slowing down) I decided that it's ridiculously slow.
So back to the thinking board.
In this particular case a heightfield would do (it wouldn't work
in all cases, but this one was simple enough). However, how to create
the heightfield?
I came to the conclusion that creating a heighfield from my recursive
function was just impossible. So instead, I had to create a mesh.
Of course the mesh is also impossible to be created from the function
directly, at least without sampling the function. But that's actually
exactly what the isosurface is doing: It samples the function until
it finds the surface.
So I created the (300x300x2 triangles) mesh by tracing the isosurface.
The tracing was very slow, of course, but I still got this image
ready in 42 minutes (rendering the isosurface directly would probably
have taken more than a day).
Curiously, it also has the noise, probably because the mesh is so
accurate. But at least I got it faster.
Post a reply to this message
Attachments:
Download 'juliamorph.jpg' (75 KB)
Preview of image 'juliamorph.jpg'
|
|
| |
| |
|
|
|
|
| |
| |
|
|
As my wife often says to me when I'm POVing "but why are you doing it?"
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
| |
|
|
> Since fractals seem to be the theme nowadays, here's my shot at it.
>
> There's quite a developement history behind this image.
>
> The basic idea was this: What if you take a julia fractal and then
> extrude it (a bit like a prism), but while you extrude it, change
> the complex number from which the julia is being calculated? That is,
> different layers of the prism are composed of julia fractals with
> slightly modified values.
>
> Allright, so take the julia fractal for example for <0.353, 0.288>
> and extrude it by half a unit so that at the other end it is the
> julia for <0.353+0.25, 0.288>. 10 iterations should be ok.
Sounds rather like FractInt's "Julibrot" type. Lots of normal 2D Julia
sets, layered one on top of the other to create a 3D form. (Or, but it
another way, taking the 4D space defined by the set of all possible z0
and c and taking a 3D slice out of it.)
http://spanky.fractint.org/www/fractint/juliabrot_type.html
> How exactly to implement this was in no way trivial.
>
> My first thought was to make an isosurface using the julia fractal
> pattern as a function. So far so good, but pattern functions can't take
> parameters, so it can't be done like that.
>
> So I had to actually make the julia fractal function, in other words
> a recursive function myself (it's slower, of course, but works).
>
> I got the isosurface to work, but it had one problem: Not accurate
> enough. The surface was full of noise. I had to lower the accuracy
> by two orders of magnitude in order to get a smooth surface, but at
> the cost of a ridiculously high max_gradient (over 20000). Not good.
>
> So I settled on a compromise: accuracy 1e-4, max_gradient 2000.
> It still had some noise, but not as much. Bearable.
>
> However, it was still not good: After 1.5 hours of rendering the
> final version and when only about 10% was ready (and it was only
> slowing down) I decided that it's ridiculously slow.
>
> So back to the thinking board.
I had similar problems with my cubic Mandelbrot slices. I found that
inserting max(fn(...), 8) ment I could lower the max_gradient
*significantly* with no change to the image. In effect, the function is
steepest at the point most distant from the surface. (It's not
shallowest at the surface - slightly inside it actually. But it gets
steeper as you move away.)
Champing the top of the function to a small maximum value means that big
areas of empty space get sampled at the minimum density (because the
max_gradiant tells POV-Ray it would take ages for the function to decay
far enough to reach zero). Or at least, that's my theory......
I also tried taking the logarithm - but that afforded no notable change
in speed. I hypothesise that the extra time to compute the logarithm
destroys any benefit in less sampling of the function.
The other thing I've tried before is spliting space into a zillion tiny
cubes, and using some parse-time stuff to figure out which of those
cubes actually have some surface inside them. Then I have POV-Ray only
bother rendering those. Of course, this isn't quick either... (And prone
to cubes being "missed". I think I had a bug somewhere!)
Post a reply to this message
|
|
| |
| |
|
|
|
|
| |
|
|