News: Support us via Flattr FLATTR Link  ## The All New FractalForums is now in Public Beta Testing! Visit FractalForums.org and check it out!

 Pages:    Go Down       Author Topic: How do I convert a Mandelbrot to a Mandelbulb?  (Read 1779 times) Description: Convert Mandelbrot ot Mandelbulb 0 Members and 1 Guest are viewing this topic.
Bottleneck
Guest « on: December 03, 2011, 01:52:42 PM »

Hi,
First of all I want to thank you for letting me use your forums. Very much appreciated. Now my problem is I'm trying to convert a Mandelbrot to a Mandelbulb.
The Mandelbrot code comes from one of the Nvidia samples that you get when you install their Cuda SDK.
(on a side note: The calculated mandelbrot data is saved in a texture which is rendered using OpenGL)

TL;DR: So how do I convert a Mandelbrot to a Mandelbulb?
 « Last Edit: December 04, 2011, 01:44:25 AM by Bottleneck » Logged
eiffie
Guest « Reply #1 on: December 03, 2011, 05:45:01 PM »

Start by learning the math. Check the mandelbulb wiki. Instead of complex numbers, triplex numbers are used and
Z=Z^2+C becomes:(in glsl)

float r=length(Z);   //Z is now a 3d vector
float zo = asin(Z.z / r) * p;  //p is power, usually 8 instead of 2
float zi = atan(Z.y, Z.x) * p;
Z=pow(r,p)*vec3(cos(zo)*cos(zi),cos(zo)*sin(zi),sin(zo))+C; //there are variations to this swapping sin/cos

But now you have a bigger problem - how to render a 3d object to a 2d screen.
Learn about ray-marching with distance estimation. A distance estimation formula tells you how far you can safely move the ray until you need to check again. A mandelbulb DE formula looks like this:
float DE(vec3 Z){
vec3 C=Z;
float dr = 1.0; //this is a running derivative
float r = length(Z);
for (int n = 0; n < iterations && r<2.0; n++) {//about 7 iterations will do for starters
float zo = asin(Z.z / r) * p;
float zi = atan(Z.y, Z.x) * p;
float zr = pow(r, p-1.0);
dr = dr * zr * p + 1.0; //do you see what is meant by a running derivative here?
Z=zr*r*vec3(cos(zo)*cos(zi),cos(zo)*sin(zi),sin(zo))+C;
r = length(Z);
}
return 0.5*r*log(r)/dr;
}
TL;DR: Check out Boxplorer code for an OpenGL sample.
Oh wait a MandelBOT!?! Sorry can't help « Last Edit: December 03, 2011, 05:57:54 PM by eiffie » Logged
Guest « Reply #2 on: December 03, 2011, 06:51:34 PM »

Help me understand?

A ray is cast from every 2D camera point away from the camera. At the face of the camera, each 2D point has a ray-march of 0 (I'm making up names), which correlates to a vec3(Z) in 3D space.  That Z can be plugged into the 3D formula to determine whether a point in 3D space is inside the boundary of the fractal.

Ray-marching could iterate steps away from the camera, but it's too inefficient, so the DE() function returns an estimated step distance for the ray to march forward.  In other words, the ray starts at the camera lens and is iterated forward by ray1=DE(ray0), which 3D space point is then plugged into the fractal formula "is this inside the boundary?", if not, ray2=DE(ray1), to iterate it forward until it reaches the boundary.

Is this correct?

(And if so, aren't binary searches more efficient?   And if you store the adjacent 2D point's DE, can it contribute to this point's DE?)
 « Last Edit: December 03, 2011, 07:14:50 PM by huminado » Logged
eiffie
Guest « Reply #3 on: December 03, 2011, 08:01:18 PM »

Very good. When the return value dist=DE(ray) is less than the size of a pixel at that distance than you quit and say I hit the fractal. Like this
rayDir is the normalized direction of the ray march
ray is the point we are testing, it starts at the camera lens
eps is an estimate of the pixel size
maxRayLen is the bound and marching steps can vary, about 100 to start
for(int i=0;i<marchingSteps && dist>eps && rayLength<maxRayLen;i++){
rayLen+=dist=DE(ray+rayLen*rayDir);
}
This is actually quite fast! Think about a simple DE like a sphere of radius 1...
float DE(Z){return length(Z)-1.0;}
If you are aiming right at it you hit in 1 step. If you miss it completely it takes a few more and you reach maxRayLen.
The interesting part is near the edges. This will take many steps and may seem inefficient but the number of steps gives you an approximate occlusion of light so you could even just color the fractal with...
color=diffuse*(1.0-float(i)/float(marchingSteps));

But thats your next step learning lighting calculations.

Yes there are programs that use monte carlo methods etc. If you are using the GPU each pixel is oblivious of its neighbors.
The method I've described runs near real time depending on your hardware. Many thanks to the folks here who have contributed to it!
 « Last Edit: December 03, 2011, 08:13:36 PM by eiffie » Logged
Guest « Reply #4 on: December 03, 2011, 10:01:13 PM » Logged
 Related Topics Subject Started by Replies Views Last post  Mandelbulb Bitten, and finding the MANDELBROT again. Meet & Greet mrrgu 13 3837 January 06, 2010, 05:01:57 PM by Nahee_Enterprises  2d Mandelbrot in Mandelbulb? The 3D Mandelbulb avvie 5 3137 February 15, 2010, 09:57:08 AM by bib  Need help to convert (ABS( 1.0 - SQRT(1-(4*c)) ) to C Programming ker2x 9 680 September 20, 2010, 05:31:16 PM by Rrrola  Convert a Distance Estimate to a Mesh General Discussion eiffie 9 5948 October 11, 2011, 05:22:34 PM by eiffie  Easier to convert to .obj feature request cyseal 11 2046 December 10, 2015, 12:06:16 AM by thargor6