POV-Ray : Newsgroups : povray.general : f_mandelbulb() 0.1.0 Server Time
30 Jul 2024 04:16:33 EDT (-0400)
  f_mandelbulb() 0.1.0 (Message 1 to 3 of 3)  
From: waggy
Subject: f_mandelbulb() 0.1.0
Date: 19 Dec 2009 02:10:26
Message: <4b2c7c62$1@news.povray.org>
I am pleased to offer for discussion, dissection, and debate a set of 
files for rendering the mandelbulb fractal in POV-Ray.  The heart of it 
can be put into a single standalone file, the SDL version of which I 
have reproduced at the bottom of this message.  The rest of the example 
scene files, and a few other goodies including a long README.TXT, are 
zipped up and posted to p.b.scene-files.

http://news.povray.org/povray.binaries.scene-files/thread/%3C4b2c7b3f%40news.povray.org%3E/

In this zip you can also find files to patch beta 34 for about a 6x 
speedup by compiling the function internally, but I have also included 
SDL-only versions like the one below that work just fine with POVRay 
3.6.1 for MS Windows, and in the unpatched 3.7 beta in both MSW and 
Linux.  (These are the only systems I have tested.)  All of these files 
render in minutes (some in seconds) at 320x240 without anti-aliasing.

Ultimately, if the source code patch in the following post to this 
thread can be made acceptable, I would like to post it to p.u.patches 
and hope for its inclusion in an upcoming version of POV-Ray.

I appreciate your comments and critiques.

~David Wagner

//--- Start of file ---

// Persistence of Vision Ray Tracer Scene Description File
// File: mbsdl_standalone.pov
// Vers: 3.6, 3.7
// Desc: Minimal Stand-alone Mandelbulb Scene Example
// Date: 12/18/09
// Auth: David Wagner
// Cite: http://www.skytopia.com/project/fractal/2mandelbulb.html

// WARNING: Declare this function definition first in a scene.
// WARNING: This recursive function is invalid SDL and can crash POV-Ray.

#declare mbsdl_recurse = function( mbsdl_r_p_r, mbsdl_r_p_theta, 
mbsdl_r_p_phi, mbsdl_r_i,mbsdl_r_i_bailout, mbsdl_r_r2_bailout, x,y,z, 
mbsdl_r_x,mbsdl_r_y,mbsdl_r_z) {
    select(mbsdl_r_i > mbsdl_r_i_bailout | pow(mbsdl_r_x,2) + 
pow(mbsdl_r_y,2) + pow(mbsdl_r_z,2) >mbsdl_r_r2_bailout, 0,
       mbsdl_recurse( mbsdl_r_p_r,mbsdl_r_p_theta, mbsdl_r_p_phi, 
mbsdl_r_i+1,mbsdl_r_i_bailout, mbsdl_r_r2_bailout, x,y,z,

          x + pow(pow(mbsdl_r_x,2) + pow(mbsdl_r_y,2) + pow(mbsdl_r_z,2) 
, 0.5*mbsdl_r_p_r)
              * sin( atan2( sqrt(pow(mbsdl_r_x,2) + pow(mbsdl_r_y,2)), 
mbsdl_r_z) * mbsdl_r_p_theta)
              * cos( atan2(mbsdl_r_y,mbsdl_r_x) * mbsdl_r_p_phi),

          y + pow(pow(mbsdl_r_x,2) + pow(mbsdl_r_y,2) + pow(mbsdl_r_z,2) 
, 0.5*mbsdl_r_p_r)
              * sin( atan2( sqrt(pow(mbsdl_r_x,2) + pow(mbsdl_r_y,2)), 
mbsdl_r_z) * mbsdl_r_p_theta)
              * sin( atan2(mbsdl_r_y,mbsdl_r_x) * mbsdl_r_p_phi),

          z + pow(pow(mbsdl_r_x,2) + pow(mbsdl_r_y,2) + pow(mbsdl_r_z,2) 
, 0.5*mbsdl_r_p_r)
              * cos( atan2( sqrt(pow(mbsdl_r_x,2) + pow(mbsdl_r_y,2)), 
mbsdl_r_z) * mbsdl_r_p_theta)
       ),
       1/( mbsdl_r_i+log(log(mbsdl_r_r2_bailout) / 
log((mbsdl_r_i>(mbsdl_r_i_bailout-1))+pow(mbsdl_r_x,2)+pow(mbsdl_r_y,2)+pow(mbsdl_r_z,2)))

/ log(mbsdl_r_p_r) )
    )//end recursion select loop
};

#declare f_mandelbulb = function(x,y,z, mbsdl_f_p_r, mbsdl_f_p_theta, 
mbsdl_f_p_phi,  mbsdl_f_i_bailout, mbsdl_f_r_bailout){
     mbsdl_recurse( mbsdl_f_p_r, mbsdl_f_p_theta, 
mbsdl_f_p_phi,1,int(mbsdl_f_i_bailout-1), pow(mbsdl_f_r_bailout,2), 
x,y,z, x,y,z)
}

isosurface {
    function{f_mandelbulb(x,y,z, 8,8,8, 3, 3)}
    threshold 1/3.1
    max_gradient 20
    accuracy 0.001
    contained_by{sphere{<0,0,0>,1.2}}
    texture{
       pigment{rgb<1,1,1>}
    }
}

light_source {
    <-30, 30, -30>
    color rgb <1, 1, 1>
    translate <-30, 30, -30>
}

camera {
    location  <0.0, 0.5, -4.0>
    direction 1.5*z
    right     x*image_width/image_height
    look_at   <0.0, 0.0,  0.0>
}

//--- End of File ---


Post a reply to this message

From: waggy
Subject: Re: f_mandelbulb() 0.1.0 [The Patch]
Date: 19 Dec 2009 02:12:42
Message: <4b2c7cea$1@news.povray.org>
--- fnintern.cpp	Fri Dec 18 10:02:13 2009
+++ /usr/src/povray-3.7.0.beta.34/source/backend/vm/fnintern.cpp	Fri Dec 
18 10:01:10 2009
@@ -223,6 +223,7 @@
  DBL f_noise3d(FPUContext *ctx, DBL *ptr, unsigned int fn); // 76
  DBL f_pattern(FPUContext *ctx, DBL *ptr, unsigned int fn); // 77
  DBL f_noise_generator(FPUContext *ctx, DBL *ptr, unsigned int fn); // 78
+DBL f_mandelbulb(FPUContext *ctx, DBL *ptr, unsigned int fn); // 79

  void f_pigment(FPUContext *ctx, DBL *ptr, unsigned int fn, unsigned 
int sp); // 0
  void f_transform(FPUContext *ctx, DBL *ptr, unsigned int fn, unsigned 
int sp); // 1
@@ -314,6 +315,7 @@
  	{ f_noise3d,                 0 + 3 }, // 76
  	{ f_pattern,                 0 + 3 }, // 77
  	{ f_noise_generator,         1 + 3 }, // 78
+	{ f_mandelbulb,              5 + 3 }, // 79
  	{ NULL, 0 }
  };

@@ -325,7 +327,7 @@
  	{ NULL, 0 }
  };

-const unsigned int POVFPU_TrapTableSize = 79;
+const unsigned int POVFPU_TrapTableSize = 80;
  const unsigned int POVFPU_TrapSTableSize = 3;


@@ -1270,6 +1272,43 @@
  	return Noise(Vec, ngen);
  }

+DBL f_mandelbulb(FPUContext *ctx, DBL *ptr, unsigned int) // 79
+{  // Coded by David Wagner,
+	// based on Daniel White's formula at 
http://www.skytopia.com/project/fractal/2mandelbulb.html#formula
+	// and Abram Hindle's patch at 
http://softwareprocess.us/index.cgi/Mandelbulb
+	DBL x = PARAM_X, y = PARAM_Y, z = PARAM_Z;
+	DBL p_r       = PARAM(0);// Radial power.
+	DBL p_theta	  = PARAM(1);// Power around theta (usually the same as p_r).
+	DBL p_phi     = PARAM(2);// Power around phi (usually the same as p_r).
+	int i_bailout = PARAM(3);// Maximum number of iterations.
+	DBL r_bailout = PARAM(4);// Assumed divergence radius, usually 3.
+	int i=1;
+	DBL r2_bailout, r2, rp, ptheta, pphi, rpsinptheta;
+	r2_bailout = pow(r_bailout,2);
+	r2 = pow(x,2) + pow(y,2) + pow(z,2) ;
+	while(i < i_bailout && r2 < r2_bailout) {
+		 ++i;
+		 rp          = pow(r2,0.5*p_r);
+		 ptheta      = p_theta * atan2(sqrt(pow(x,2) + pow(y,2)), z);
+		 pphi	       = p_phi   * atan2(y,x);
+		 rpsinptheta = rp * sin(ptheta);
+		 x = PARAM_X + rpsinptheta * cos(pphi);
+		 y = PARAM_Y + rpsinptheta * sin(pphi);
+		 z = PARAM_Z + rp * cos(ptheta);
+		 r2 = pow(x,2) + pow(y,2) + pow(z,2);
+   }
+   // The return value corresponds to a smoothed inverted iteration count,
+   // for a range from near zero for many iterations,
+   // through 1/3 at three iterations, 1/2 at two, and unity at one 
iteration;
+   // and greater than one if the starting point is already outside the 
assumed divergence radius.
+   if (i < i_bailout) {
+       return 1/( i + log(log(r2_bailout) / log(  r2)) / log(p_r) );
+   }
+   else {
+       return 1/( i + log(log(r2_bailout) / log(1+r2)) / log(p_r) );
+   }
+}
+
  void f_pigment(FPUContext *ctx, DBL *ptr, unsigned int fn, unsigned 
int sp) // 0
  {
  	VECTOR Vec = { PARAM_N_X(5), PARAM_N_Y(5), PARAM_N_Z(5) };


Post a reply to this message

From: waggy
Subject: Re: f_mandelbulb() 0.1.0
Date: 27 Dec 2009 19:10:17
Message: <4b37f769$1@news.povray.org>
[Oops, I did it again, posting binaries to a non-binary group.  Bad 
waggy!  I really should get more sleep.]

This is just to let y'all know I am changing the function to accept an 
additional phase parameter* that allows generating four variations of 
the mandelbulb, and can be used to smoothly vary among them.  The 
function previously used what is known as the "Cosine Variation", which 
corresponds to phase=-pi/2.

I'll recompile tonight, and do a little something to eliminate the 
near-duplicate scene files, then repost the zip.  Meanwhile, below is 
mbsdl_standalone.pov with the new function.

~David

*Paul Nylander came up with this phase parameter.
http://www.fractalforums.com/videos/3d-mandelbrot-set-phase-shift-animations/

More information about the mandelbulb formula variations can be found on 
his website.
http://www.bugman123.com/Hypercomplex/index.html


//--- Start of file ---

// Persistence of Vision Ray Tracer Scene Description File
// File: mbsdl_standalone.pov
// Vers: 3.6, 3.7
// Desc: Minimal Stand-alone Mandelbulb Scene Example
// Date: 12/18/09
// Auth: David Wagner
// Cite: http://www.skytopia.com/project/fractal/2mandelbulb.html

// WARNING: Declare this function definition first in a scene.
// WARNING: This recursive function is invalid SDL and can crash POV-Ray.

#declare mbsdl_recurse = function( mbsdl_r_p_r, mbsdl_r_p_theta, 
mbsdl_r_p_phi, mbsdl_r_phase, mbsdl_r_i,mbsdl_r_i_bailout, 
mbsdl_r_r2_bailout, x,y,z, mbsdl_r_x,mbsdl_r_y,mbsdl_r_z) {
    select(mbsdl_r_i > mbsdl_r_i_bailout | pow(mbsdl_r_x,2) + 
pow(mbsdl_r_y,2) + pow(mbsdl_r_z,2) >mbsdl_r_r2_bailout, 0,
       mbsdl_recurse( mbsdl_r_p_r,mbsdl_r_p_theta, mbsdl_r_p_phi, 
mbsdl_r_phase, mbsdl_r_i+1,mbsdl_r_i_bailout, mbsdl_r_r2_bailout, x,y,z,

          x + pow(pow(mbsdl_r_x,2) + pow(mbsdl_r_y,2) + pow(mbsdl_r_z,2) 
, 0.5*mbsdl_r_p_r)
              * cos( atan2(mbsdl_r_y, mbsdl_r_x) * mbsdl_r_p_theta )
              * cos( atan2(mbsdl_r_z, sqrt(pow(mbsdl_r_x,2) + 
pow(mbsdl_r_y,2)) )
                     * mbsdl_r_p_phi + mbsdl_r_phase),

          y + pow(pow(mbsdl_r_x,2) + pow(mbsdl_r_y,2) + pow(mbsdl_r_z,2) 
, 0.5*mbsdl_r_p_r)
              * sin( atan2(mbsdl_r_y, mbsdl_r_x) * mbsdl_r_p_theta)
              * cos( atan2(mbsdl_r_z, sqrt(pow(mbsdl_r_x,2) + 
pow(mbsdl_r_y,2)) )
                     * mbsdl_r_p_phi + mbsdl_r_phase),

          z + pow(pow(mbsdl_r_x,2) + pow(mbsdl_r_y,2) + pow(mbsdl_r_z,2) 
, 0.5*mbsdl_r_p_r)
              * sin( atan2(mbsdl_r_z, sqrt(pow(mbsdl_r_x,2) + 
pow(mbsdl_r_y,2)) )
              * mbsdl_r_p_phi + mbsdl_r_phase)
       ),
       1/( mbsdl_r_i+log(log(mbsdl_r_r2_bailout) / 
log((mbsdl_r_i>(mbsdl_r_i_bailout-1))+pow(mbsdl_r_x,2)+pow(mbsdl_r_y,2)+pow(mbsdl_r_z,2)))

/ log(mbsdl_r_p_r) )
    )//end recursion select loop
};

#declare f_mandelbulb = function(x,y,z, mbsdl_f_p_r, mbsdl_f_p_theta, 
mbsdl_f_p_phi, mbsdl_f_phase, mbsdl_f_i_bailout, mbsdl_f_r_bailout){
     mbsdl_recurse( mbsdl_f_p_r, mbsdl_f_p_theta, 
mbsdl_f_p_phi,mbsdl_f_phase,1,int(mbsdl_f_i_bailout-1), 
pow(mbsdl_f_r_bailout,2), x,y,z, x,y,z)
};

isosurface {
    function{f_mandelbulb(x,y,z, 8,8,8,-pi/2, 3, 3)}
    threshold 1/3.1
    max_gradient 20
    accuracy 0.001
    contained_by{sphere{<0,0,0>,1.2}}
    texture{
       pigment{rgb<1,1,1>}
    }
}

light_source {
    <-30, 30, -30>
    color rgb <1, 1, 1>
}

camera {
    location  <0.0, 0.5, -4.0>
    direction 1.5*z
    right     x*image_width/image_height
    look_at   <0.0, 0.0,  0.0>
}

//--- End of File ---


Post a reply to this message

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.