Welcome to Fractal Forums

Fractal Software => 3D Fractal Generation => Topic started by: Buddhi on July 11, 2009, 02:58:02 PM




Title: True 3D Julia
Post by: Buddhi on July 11, 2009, 02:58:02 PM
Hello!

It's my first attempt to render true 3D Julia Fractal. I used Quaternions to calculate fractal (like David Makin). Main formula is:
newx = x*x - y*y - z*z - w*w + julia_x;
newy = 2.0*x*y + 2.0*w*z + julia_y;
newz = 2.0*x*z + 2.0*y*w + julia_z;
neww = 2.0*x*w + 2.0*y*z + julia_w;

Julia coordinates:
julia_x = -1.47409435510635;
julia_y = -0.00043243408203125;
julia_z = 0.00043243408203125;
julia_w = 0;

(http://www.fractalforums.com/gallery/0/640_11_07_09_8_21_16.jpg)
http://www.fractalforums.com/gallery/?sa=view;id=733
http://picasaweb.google.com/buddhi1980/Fraktale#5357183004369014866


Title: Re: True 3D Julia
Post by: Buddhi on July 11, 2009, 07:52:55 PM
Another view and higher quality

(http://www.fractalforums.com/gallery/0/640_11_07_09_8_22_29.jpg)
http://www.fractalforums.com/gallery/?sa=view;id=734
http://picasaweb.google.com/buddhi1980/Fraktale#5357261070669030818


Title: Re: True 3D Julia
Post by: cKleinhuis on July 11, 2009, 08:22:40 PM
phew this one is stunning somhow ;)



Title: Re: True 3D Julia
Post by: lycium on July 12, 2009, 07:22:38 AM
buddhi those are some pretty cool renders you've been posting!  O0 i like the approach of pre-rendering to a large array first (good excuse to grab 12gb of ram!), and it allows the use of nice volumetric rendering techniques; might give that a crack at some stage.

keep up the interesting work :D


Title: Re: True 3D Julia
Post by: Buddhi on July 12, 2009, 09:24:23 AM
I will describe more precisely my fractal rendering technique.
Rendering process is divided into two main steps. In first step I render 3D array with fractal. My program renders it layer by layer (cross-sections) from z = z_min to z_max into sequence of JPEG images (quality 100%). When I want to render array of size 1500x1500x1500 pixels I have to render 1500 images with layers. I chose JPEG format because It takes less space in hard disk than BMP and with fast CPU it's faster to load (less amount data to transfer from hard disk).  Each layer is rendered in classic technique like 2D fractals. Pixels intensity are proportional to number of fractal iteration. When array is ready it's time for step 2.
It's difficult to visualise that big array 3D array on 2D screen. Fractals don't have surfaces and it's imposible to use standard 3D rendering techniques. It's not able (or I dont'y know how) to convert these arary of pixels to 3D triangles and calculate normal vectors of surfaces to calculate shades. I use completely anoder technique. It's something like raytracing but much more simple. From each pixel of 3D array where some details of fractal are present I send about 50 beams in nearly the same direction (45 degrees cone directed to light source) and analyse damping of light along beams. When beam is going through pilxels of higher values dumping is higher. In that way I acheve something like shading and shadows. When calculation of light intensity is done I put this pixel on screen with opacity proportional to numer of 3D pixel intensity (number of fractal iterations). Program has to do the same whith all of pixels of array where values are bigger than zero starting from bottom layer and back pixels. This alghotitm takes lots of memory. Memory cunsumption = array_width * array_height * array_depth when maximum number of iteration is 256 (only 8 bits per pixel). For example to render array of size 1500x1500x1500 program needs 3,3GB RAM memory. However this aghorithm is very fast because the slowest iteration calculations are made only one time. Of course to make this for example in C++ you need 64-bit compiler on 64-bit operating system because on 32-bit system there is limitation to allocate only 2GB of RAM by one process. One time rendered 3D array I can use to make many different vievs of the same fractal.

For writing my programs I use Eclipse SDK and I'm making everything in C or C++. Now I'm using Linux (Ubuntu) because only on Linux there is free 64-bit C++ IDE and this operating system is very good to operate with very large amount of memory. I have 4GB RAM in my computer and I tested this system with 11GB memory usage (virtual memory) and it works very well.
I each program I try to use all of four CPU cores by dividing rendering process into four threads. Sometimes it's very difficult to make but it's only way to achieve good deficiency on multi-core CPUs.


Title: Re: True 3D Julia
Post by: David Makin on July 12, 2009, 06:14:20 PM
Fractals don't have surfaces and it's imposible to use standard 3D rendering techniques.

Just to point out that "Fractals don't have surfaces" is not strictly correct - they do have surfaces it's just that the true (infinite limit) surface is purely theoretical.
When rendering 3D/4D fractals the render always compromises by limiting the max. iteration depth and a given fractal formula at a given iteration depth does have a concrete, finite surface defined by |In(f(z))|=bailout i.e. the surface is where the magnitude of the nth iterate of f(z) is equal to the bailout value - the whole solid being defined by |In(f(z))|<=bailout.
As to ways of calculating the normals, I simply use the "found" surface adjacent "found" pixels method (or better still half-pixel offsets) that's good but doesn't show any sub-pixel detail - for that it's better to use a method such as the one you employ or to use the iteration density at pixel or sub-pixel offsets (or to find "solid" based on DE instead of iteration and do the same thing with the DE at pixel/sub-pixel offsets).

I'm still attempting to find a killer algorithm that will allow solid based on any colouring algorithm, see:

(http://fc09.deviantart.com/fs9/f/2006/062/2/c/Alien_Interface_200.gif)

If no image above:

http://makinmagic.deviantart.com/art/Alien-Interface-ANIM-29854835 (http://makinmagic.deviantart.com/art/Alien-Interface-ANIM-29854835)

That's a Julibrot solid on orbit trapping but in order to get (almost) visually flawless results I had to severely limit the max. iteration count (<10), I want to develop an algorithm that will render something similar but at say 60 iterations or even higher visually "accurately" and in reasonable times but without having to use masses of memory.

These attempts at pure raycasting orbit-trap heightfields illustrate the problem:

http://makinmagic.deviantart.com/art/Orbit-Trap-Heightfield-128850151 (http://makinmagic.deviantart.com/art/Orbit-Trap-Heightfield-128850151)
http://makinmagic.deviantart.com/art/Orbit-Trap-Height-Detail-128912127 (http://makinmagic.deviantart.com/art/Orbit-Trap-Height-Detail-128912127)


Title: Re: True 3D Julia
Post by: David Makin on July 12, 2009, 09:40:43 PM
These attempts at pure raycasting orbit-trap heightfields illustrate the problem:

http://makinmagic.deviantart.com/art/Orbit-Trap-Heightfield-128850151 (http://makinmagic.deviantart.com/art/Orbit-Trap-Heightfield-128850151)
http://makinmagic.deviantart.com/art/Orbit-Trap-Height-Detail-128912127 (http://makinmagic.deviantart.com/art/Orbit-Trap-Height-Detail-128912127)


Just to add that the problem here is that unlike using solid based on iteration/smooth iteration or solid based on Distance Estimation where there is a fairly smooth progression to "inside" in orbit trapping each separate orbit minimum is a hard break from the neighbouring minima (as can be seen in the detal version above).


Title: Re: True 3D Julia
Post by: Buddhi on July 12, 2009, 10:28:33 PM
Some another examples of 3D Julia
Both of them has nearly the same coordinates. First is located on 2D surface (z=0) and second little below this surface. Second is much more transparent and has very thin contour.
(http://www.fractalforums.com/gallery/0/640_12_07_09_9_43_50.jpg)(http://www.fractalforums.com/gallery/0/640_12_07_09_9_45_48.jpg)
http://picasaweb.google.com/buddhi1980/Fraktale#5357659098277483730
http://picasaweb.google.com/buddhi1980/Fraktale#5357659127406191426

coordinates:
first:
x = -0.817795
y = -0.2000035
z = 0
w = 0
256 iterations

second:
x = -0.817795
y = -0.2000035
z = -0.2000035
w = 0
256 iterations

When I optimise rendering code I will render some animation with morphing Julia fractal. Now I need about 1 hour to render one frame. I'd like to know what happen when move Julia point along fourth (w) dimension. Maybe somebody checked this?

About surfaces in fractals I'm agree with you that fractals has surfaces when we make calculation with some finite maximum number of iterations. But when iterations number is very high we have lots of separate points (when we have finite resolution of rendering) and edges are very irregular. Secondly I like to render 3D fractals with "fog" which density is proportional to iterations number similar to standard 2D Mandelbrot fractals. Sometimes it looks very interesting. Your method is also very good because you can add light reflections and I think needs less amount of memory to render. Could you write more details about finding normals? It's very interesting topic.



Title: Re: True 3D Julia
Post by: lycium on July 13, 2009, 12:39:21 AM
for estimating the normal, you can use a central difference approximation to the grad of the potential function.


Title: Re: True 3D Julia
Post by: David Makin on July 13, 2009, 01:13:07 AM
for estimating the normal, you can use a central difference approximation to the grad of the potential function.

Exactly - the only problem with this method is that at higher iteration levels it can lead to serious aliasing in areas where the iteration density changes are way sub-pixel.
It works much better for solid based on distance estimator than solid based on iteration - i.e. for DE use a central difference approximation of the gradient of the distance estimate.



Title: Re: True 3D Julia
Post by: lycium on July 13, 2009, 01:17:47 AM
on the other hand, buddhi has a perfect regularly-spaced potential function. this also serves to cap the variance of the normal estimate  O0


Title: Re: True 3D Julia
Post by: David Makin on July 13, 2009, 01:31:31 AM
on the other hand, buddhi has a perfect regularly-spaced potential function. this also serves to cap the variance of the normal estimate  O0

That's interesting, I didn't realise that it would actually help that much, but then again I've never tried rendering them using a fixed grid - something which I now have an idea for in UF - at least for storing in a scanline format, for each zscan store distance to first solid, distance to first space, distance to next solid..... This would use massively less memory than rendering and storing whole 2D slices and I could probably do it in UF - even maybe saving a "whole" scanned object as a png image for import back into UF and rendering at any angle very quickly indeed.....


Title: Re: True 3D Julia
Post by: lycium on July 13, 2009, 01:47:18 AM
there are much more powerful optimisations you could make if you'd unshackle yourself from ultrafractal :P instead of rendering scanlines, if you render along vertical lines from bottom to top you can save a ton of traversal steps (draw it on paper and you'll see what i mean).

it's a bit of a mystery to me why choose to code in that hideous (and hideously slow) language, running the result on 32bit windows emulated on a true 64bit operating system!


Title: Re: True 3D Julia
Post by: David Makin on July 13, 2009, 02:21:15 AM
there are much more powerful optimisations you could make if you'd unshackle yourself from ultrafractal :P instead of rendering scanlines, if you render along vertical lines from bottom to top you can save a ton of traversal steps (draw it on paper and you'll see what i mean).

it's a bit of a mystery to me why choose to code in that hideous (and hideously slow) language, running the result on 32bit windows emulated on a true 64bit operating system!

I hadn't considered along which 3D axis to do the scanlines :)
> hideously slow ?
Hmmm - I don't think that rendering a distance estimated 3D quat in under 5 secs (on this P4HT) at 640*480 is that slow....or a Menger sponge in 13.2 secs...
Example Quat (4.53 secs):
(http://www.fractalforums.com/gallery/0/141_13_07_09_2_10_44.jpg)

Also I can only do fractal stuff on this old P4HT or my core2duo laptop - the dual quadcore MacPro is the machine where I work - it's not mine unfortunately.
When I finally get a Mac I'll start writing some custom fractal software (Objective C/assembler), but I'm simply not prepared to use Microsoft development software anymore (unless payment is guaranteed) (same goes for Symbian) :)


Title: Re: True 3D Julia
Post by: David Makin on July 13, 2009, 02:51:23 AM
there are much more powerful optimisations you could make if you'd unshackle yourself from ultrafractal :P instead of rendering scanlines, if you render along vertical lines from bottom to top you can save a ton of traversal steps (draw it on paper and you'll see what i mean).

I hadn't considered along which 3D axis to do the scanlines :)

I meant I would render the step information to a 3D scanline buffer in the global section and then turn that buffer into an image for export - I didn't mean using UF's scanline loop section.


Title: Re: True 3D Julia
Post by: Buddhi on August 22, 2009, 09:12:54 AM
Hi
I stay with my render method. It needs lots of memory and it's very slow but I can generate accurate shadows, transparent fog, environment mapping (based on normal vectors). Now I'm working to prepare full raytracing (with reflections). I agree with you that distance estimation method will be helpfull for rendering because this distance information we can use to calculate step distance in for example raytracing algorithm.  Rendering will be much more faster. But now I know how to calculate distance only using quaternions. Quaternions fractals has unfortunately few interesting details.
Below there is new rendering of Julia fractal.
(http://www.fractalforums.com/gallery/0/640_22_08_09_8_40_10.jpg)



Title: Re: True 3D Julia
Post by: Buddhi on October 23, 2009, 04:04:24 PM
Last times I have rendered two new Julia 3D Fractals using Twinbee formula. For shading I used global illumination and hard shadows algorithms.

Julia constant  = -0.78 + 0.15i + 0.07j
(http://www.fractalforums.com/gallery/0/640_19_10_09_8_15_53.jpg)
http://www.fractalforums.com/gallery/?sa=view;id=1000

Julia constant  = -0.4360393 + 0.0147539i + 0j
(http://www.fractalforums.com/gallery/1/640_23_10_09_3_56_30.jpg)
http://www.fractalforums.com/gallery/?sa=view;id=1017



Title: Re: True 3D Julia
Post by: David Makin on October 23, 2009, 08:08:15 PM
Awesome renders !


Title: Re: True 3D Julia
Post by: cKleinhuis on October 24, 2009, 04:04:16 AM
indeed
 :thumbsup1:


Title: Re: True 3D Julia
Post by: lycium on October 24, 2009, 04:37:25 AM
global illumination and hard shadows algorithms

even if that's a contradiction, i must also agree: very fine renders!


Title: Re: True 3D Julia
Post by: cKleinhuis on October 24, 2009, 04:53:34 AM
as i said in the gallery, the first of the last 2 really looks like a coral water plant ... actually REALLY IN the water!  :elvis:


Title: Re: True 3D Julia
Post by: JColyer on December 04, 2009, 02:36:56 PM
@buddhi - i've been working on a similar rendering technique to yours for about the past week or so, biggest difference is that I'm storing my pre-render data in a DB instead of JPEG files.  I've gotten quite far in the ray-tracing process but i'm having a devil of a time trying to figure out how to come up with the normals?  any suggestions or guidance you can offer?

thanks!

JC


Title: Re: True 3D Julia
Post by: Buddhi on December 04, 2009, 05:44:55 PM
@JColyer - bellow is some fragment of code from my program where is procedure for calculation normal vector. This algorithm calculates average gradient for some small area near calculated point.
Code:
for(int k=-smooth; k<=smooth; k++)
{
for(int j=-smooth; j<=smooth; j++)
{
for(int i=-smooth; i<=smooth; i++)
{
double delta2X = Interpol3D(x+0.5+i,y+0.5+j,z+0.5+k,fractal3D)
            -Interpol3D(x-0.5+i,y-0.5+j,z-0.5+k,fractal3D);
double delta2Y = Interpol3D(x+0.5+i,y+0.5+j,z+0.5+k,fractal3D)
            -Interpol3D(x-0.5+i,y-0.5+j,z-0.5+k,fractal3D);
double delta2Z = Interpol3D(x+0.5+i,y+0.5+j,z+0.5+k,fractal3D)
            -Interpol3D(x-0.5+i,y-0.5+j,z-0.5+k,fractal3D);
deltaX+=delta2X;
deltaY+=delta2Y;
deltaZ+=delta2Z;
        }
        }
}
                   
//length of vector (normalization factor)
double modul = sqrt(deltaX*deltaX + deltaY*deltaY + deltaZ*deltaZ);
           
if(modul>0.001)
{
      //normalization of normal vector
        normalX = deltaX/modul;
        normalY = deltaY/modul;
        normalZ = deltaZ/modul;
}

Interpol3D function calculates linear interpolation between adjacent points of 3D array which consist fractal slices. It is for more smooth results.

I know that it is not optimal algorithm but this is only one I know. Maybe it helps you.

I resigned from pre-calculating slices into array, because it is not effective (program have to calculate points also inside Mandelbulb) and needs lots of memory. Maximum array size which I achieved was 1500x1500x1500 (3,2GiB of RAM). Unfortunately it is not enough for any perspective views. Now I'm calculating fractal iterations directly in 3D view and it is about 10 times faster than with calculated fractal slices. It is faster because program have to calculate only visible points.


Title: Re: True 3D Julia
Post by: JColyer on December 05, 2009, 01:01:08 AM
@buddhi - ah thank you, i had read about using a linear gradient function but hand't quite been able to get my brain wrapped around it.  as of last night I built a very crude fractal ray tracer and it works ok, but needs a load of work.  I'm working with dataset driven rendering as I'm rendering the interior structures of julia sets and the method I use requires post-generation data mapping to get full quality and detail from the data.  I'll get some pics posted asap!

thanks for pointing me in the right direction!

JC