Welcome to Fractal Forums

Fractal Software => 3D Fractal Generation => Topic started by: JosLeys on March 23, 2010, 12:45:39 AM




Title: A Mandelbox distance estimate formula
Post by: JosLeys on March 23, 2010, 12:45:39 AM
I found that the following very simple formula works quite well;
DE=1/(1+exp(s-4)) ,
where s is the smooth iteration value s=iters+1- log(log(R)/log(@bailout))/log(@pow).
The picture below was made using that formula (in UF)


Title: Re: A Mandelbox distance estimate formula
Post by: reesej2 on March 23, 2010, 12:56:10 AM
Very nice. This is for scale = 2, yes? Does it work equally well for other scales?


Title: Re: A Mandelbox distance estimate formula
Post by: JosLeys on March 23, 2010, 01:14:43 AM
Yes it was scale 2. Here is scale 2.5.
(Scales lower than 2 appear to be more difficult.)


Title: Re: A Mandelbox distance estimate formula
Post by: David Makin on March 28, 2010, 04:17:17 AM
Hi all, Jos sent me a copy of his method (as posted here) and I immediately asked him if it would work on Mandelbulbs etc. as well and I decided to play around to see if I could get something similar that would do so -  though I've still yet to try Jos's method on the Mandelbox properly.

The difference between implimenting these methods and the DE methods (analytical and delta) is that only a single normal iteration loop is required i.e. we don't have to iterate twice nor do we need to calculate the derivative.
The difference in the results is that these methods produce a solid where the solid isosurface is the isosurface of a given potential rather than a given distance from "inside" which means that these methods tend to have a greater variance in detail levels in the resulting renders - specifically the "busier" areas are more detailed and the less busy areas less detailed than is the case using the DE methods.
This is good because it gives us an alternative view that matches what you get if you just do "solid on given iteration".

Anyway I played around and found an adapted version of Jos' method that works for Mandelbulbs, quaternions etc., here it is:

Iterate the formula normally
Calculate the smooth iteration value
If Mandelbrot subtract 2 from the smooth iteration value, if Julia subtract 1 from it.
calculate distance value = 1.0/(adjust + divergence^smooth iteration)
test the distance value against your minimum threshold value (could be calculated directly for solid on a given iteration value)
if not hit solid then step forwrd by distance value*0.1/accuracy

Where: adjust is a user parameter (usual values 0 or 1, larger values for fractals of very high divergence), divergence is either a user parameter giving the estimated divergence of the fractal (e.g. 8 for z^8+c) or a calculated value based on the last two values of z from iteration and accuracy is a user parameter (normally 1, larger values for increased accuracy, smaller for faster less accurate renders).

Note that the 0.1 in "distance value*0.1/accuracy" is required because the behaviour of the raw smooth iteration contours is such that the calculation above for the distance value is often overestimated by up to 10 times (sometimes more but that's allowed for by allowing the accuracy parameter).

Unfortunately the method as I've outlined above doesn't work on the Mandelbox or my escape-time IFS formula, nor have I been able to get Jos' method to work for the Mandelbox - I can't seem to work out the correct parameters in a/(b+c*exp(sm-d)) !

As to timings, for the degree 8 Mandelbulb (and other similar style fractals) the method renders in times comparable to using the analytical distance estimator but is slower on simpler formulas such as quaternions, bicomplex and the various formulas based on the unit vector multiplication tables.
This is because the iteration part is faster because it's only done once or doesn't have the extra derivative calculation but the stepping is slower because the step sizes are not as accurate as the other methods.
Ignoring the visual differences in the results it's best to use the DE methods for simpler fractal formulas and this method for the more complex ones.

I hope to find a way to satisfactarily apply the method to the Mandelbox and escape-time IFS formulas tomorrow.....


Title: Re: A Mandelbox distance estimate formula
Post by: Buddhi on March 28, 2010, 06:12:20 PM
Hi

I found some interesting method for calculating Mandelbox distance estimate. It is very simple method based on calculation resultant multiplication of input values. Below is my algorithm (there are marked additional lines in code):

inside iteration loop:

DEfactor = scale;

fixedRadius = 1.0;
fR2 = fixedRadius * fixedRadius;
minRadius = 0.5;
mR2 = minRadius * minRadius;

if (x > 1.0)
x = 2.0 - x;
else if (x < -1.0) x = -2.0 - x;
if (y > 1.0)
y = 2.0 - y;
else if (y < -1.0) y = -2.0 - y;
if (z > 1.0)
z = 2.0 - z;
else if (z < -1.0) z = -2.0 - z;

r2 = x*x + y*y + z*z;

if (r2 < mR2)
{
   x = x * fR2 / mR2;
   y = y * fR2 / mR2;
   z = z * fR2 / mR2;
   DEfactor = DEfactor * fR2 / mR2;
}
else if (r2 < fR2)
{
   x = x * fR2 / r2;
   y = y * fR2 / r2;
   z = z * fR2 / r2;
   DEfactor *= fR2 / r2;
}

x = x * scale + cx;
y = y * scale + cy;
z = z * scale + cz;
DEfactor *= scale;

resultant estimated distance (after iteration loop):

distance = sqrt(x*x+y*y+z*z)/abs(DEfactor);

Results are very good. Distance is very accurate for all scale values and it doesn't need to much additional calculations.


Title: Re: A Mandelbox distance estimate formula
Post by: fractalrebel on March 29, 2010, 12:57:20 AM
Here is scale = 3 in UF using my Delta DE method:



Title: Re: A Mandelbox distance estimate formula
Post by: fractalrebel on March 29, 2010, 01:23:27 AM
Here is scale = 1.5. Its a little weird looking.



Title: Re: A Mandelbox distance estimate formula
Post by: Timeroot on March 29, 2010, 02:41:57 AM
Here is scale = 1.5. Its a little weird looking.
Looks like something is wrong. No matter what the scale value, it should always keep it's cubic symmetry...


Title: Re: A Mandelbox distance estimate formula
Post by: Tglad on March 29, 2010, 02:49:57 AM
It's just clipping the near plane. Something to watch out for.


Title: Re: A Mandelbox distance estimate formula
Post by: Timeroot on March 29, 2010, 06:47:57 AM
ooh, is it a spherical clip? It looked so... round, I guess, I wasn't expecting that. Now I feel dumb.  :embarrass:  :secret:


Title: Re: A Mandelbox distance estimate formula
Post by: fractalrebel on March 29, 2010, 05:33:56 PM
Here is a Juliabox with a seed of (2,-2,-2) and scale = 2.5, using my Delta DE method.



Title: Re: A Mandelbox distance estimate formula
Post by: JosLeys on March 29, 2010, 08:52:22 PM
Buddhi, your distance formula works like a dream! Much better than the one I suggested.


Title: Re: A Mandelbox distance estimate formula
Post by: cKleinhuis on March 29, 2010, 11:46:56 PM
awesome, this really is going to speed things up ;)


Title: Re: A Mandelbox distance estimate formula
Post by: Jesse on March 30, 2010, 10:08:41 PM
Thank you Buddhi, seems to be very fast  :)

Dont know if i made something different (the "DEfactor = scale" term is outside the loop, i guess), so far i have additional DE-scaling factors of about (MandBox) scale*1.2 + 1 for positive scales and scale*0.65 for negative scales to adjust the estimates.

But when MandBox scalings comes closer to 1 or -1, things are getting more difficult. But that hasnt changed, seems to be a global problem...

Just wondering if this method can be extended for alternated hybrids with common powerX bulbs?


Title: Re: A Mandelbox distance estimate formula
Post by: subblue on April 01, 2010, 11:08:20 AM
Thanks for the DE tip Buddhi. I'm working on a Mandelbox version of my PixelBender script. So far it is actually noticeably slower than the Mandelbulb so I've still a way to go optimising it, but the results are pretty interesting so far!

(http://farm5.static.flickr.com/4058/4479448043_057e84a815.jpg) (http://www.flickr.com/photos/subblue/4479448043/sizes/o/)

(http://farm3.static.flickr.com/2689/4480183318_095db23f97.jpg) (http://www.flickr.com/photos/subblue/4480183318/sizes/o/in/photostream/)

(http://farm5.static.flickr.com/4016/4479595087_f700beaec6.jpg) (http://www.flickr.com/photos/subblue/4479595087/sizes/o/in/photostream/)


Title: Re: A Mandelbox distance estimate formula
Post by: KRAFTWERK on April 01, 2010, 11:27:25 AM
Cool Subblue, nice images!

J


Title: Re: A Mandelbox distance estimate formula
Post by: Buddhi on April 01, 2010, 12:14:21 PM
Thanks for the DE tip Buddhi. I'm working on a Mandelbox version of my PixelBender script. So far it is actually noticeably slower than the Mandelbulb so I've still a way to go optimising it, but the results are pretty interesting so far!
Mandelbox is slower than Mandelbulb because it needs much more higher numbers of iterations. Average iteration count for most of Mandelbulbs is around 3-4 but for Mandelbox is around 15-40. I think the next reason of slower rendering with PixelBleder script is that the Mandelbox formula has many conditions and GPUs are not efficient with that kind of code.


Title: Re: A Mandelbox distance estimate formula
Post by: David Makin on April 01, 2010, 01:34:07 PM
Hi all, I have now implimented Buddhi's method and after thorough testing found that unlike the IFS (Simple Sierps) in my formula Buddhi's method works best on the Mandelbox if the "log(cabs(z))" is included in the DE calculation i.e.

DE = log(magnitude(z))*magnitude(z)/dr

Where dr is the running derivative magnitude from the iteration as described by Buddhi in this thread (except with the initial dr=scale before/outside the iteration loop).

However the problems with the value go further than just issues with smaller scales, the DE value appears to vary considerably from one area of a Mandelbox to another, for instance on a Mandelbox with scale -1.7 I found that in one area the "solid" positions found for thresholds 1e-2, 1e-3 and 1e-4 where very consistent with the position found for 1e-8 but at another location on the same Mandelbox they were well out, by up to a factor of over 100 for the 1e-4 threshold as compared to the 1e-8, in fact in general for that particular render of the -1.7 Mandelbox I had to reduce the threshold by 100* compared to normal to get close renders.

Will update the released version of the formula shortly.


Title: Re: A Mandelbox distance estimate formula
Post by: JosLeys on April 01, 2010, 04:10:47 PM
I find that using just DE=magnitude(z)/dr works without any problems and is very fast.
Taking DE = log(magnitude(z))*magnitude(z)/dr increases DE and requires a tempering factor <1 as otherwise it will overshoot in some areas.


Title: Re: A Mandelbox distance estimate formula
Post by: bib on April 01, 2010, 09:12:05 PM
I like the first image above. Looks like bricks of Lego :)


Title: Re: A Mandelbox distance estimate formula
Post by: cKleinhuis on April 01, 2010, 10:31:03 PM
i do hope you make it public soon subblue :D


Title: Re: A Mandelbox distance estimate formula
Post by: subblue on April 02, 2010, 10:34:59 PM
Mandelbox is slower than Mandelbulb because it needs much more higher numbers of iterations. Average iteration count for most of Mandelbulbs is around 3-4 but for Mandelbox is around 15-40. I think the next reason of slower rendering with PixelBleder script is that the Mandelbox formula has many conditions and GPUs are not efficient with that kind of code.

I'm managing to get reasonable results with iteration counts of around 15-20, and interaction rates of 2-3 fps at 640x480, but you're right about GPUs not handling scripts with lots of conditional execution routes routes well.

Quote from: Trifox
i do hope you make it public soon subblue
There is something odd going on with the script at the moment causing complete GPU lockup forcing hard reboot - not a pleasant experience! I might have to look at a different implementation route before it's stable enough for release.


Title: Re: A Mandelbox distance estimate formula
Post by: knighty on April 04, 2010, 12:07:32 AM
Hi,
It's possible to avoid coditionnals by using abs(), sign() and step() functions:
- The box folding may be done with:
      x = sign(x) * (1 - abs(abs(x) - 1));
      y = sign(y) * (1 - abs(abs(y) - 1));
      z = sign(z) * (1 - abs(abs(z) - 1));
- For the sphere folding:
      a = step(mr2 , r2);
      b = step(fr2 , r2);
      sscl = fr2 / mr2 * (1 - a) + a * (1 - b) * fr2 / r2 + b;
      x *= sscl;
      y *= sscl;
      z *= sscl;
      DEfactor *= sscl;

Of course you can take advantage of vectorial operations on the GPU   :)

Let me suggest a variation of Buddhi's DE that seems to give better results. :D
(Original pseudo-code by Buddhi.)
_________________________________________________
DEfactor = 1.0; (Edit: it's the initial value)

inside iteration loop:

fixedRadius = 1.0;
fR2 = fixedRadius * fixedRadius;
minRadius = 0.5;
mR2 = minRadius * minRadius;

if (x > 1.0)
x = 2.0 - x;
else if (x < -1.0) x = -2.0 - x;
if (y > 1.0)
y = 2.0 - y;
else if (y < -1.0) y = -2.0 - y;
if (z > 1.0)
z = 2.0 - z;
else if (z < -1.0) z = -2.0 - z;

r2 = x*x + y*y + z*z;

if (r2 < mR2)
{
   x = x * fR2 / mR2;
   y = y * fR2 / mR2;
   z = z * fR2 / mR2;
   DEfactor = DEfactor * fR2 / mR2;
}
else if (r2 < fR2)
{
   x = x * fR2 / r2;
   y = y * fR2 / r2;
   z = z * fR2 / r2;
   DEfactor *= fR2 / r2;
}

x = x * scale + cx;
y = y * scale + cy;
z = z * scale + cz;
DEfactor = DEfactor * abs(scale) + 1.0;

resultant estimated distance (after iteration loop):

distance = (sqrt(x*x+y*y+z*z)-abs(scale-1))/abs(DEfactor) - abs(scale)^(1-i);
_________________________________________________

(Off topic question: Have anyone tried smooth foldings? Just Wondering what it would give)


Title: Re: A Mandelbox distance estimate formula
Post by: Timeroot on April 04, 2010, 03:46:52 AM
knighty,

Do using those functions save any time? I know that, in general, functions are kind of slow to be called. For most, I bet they're handled internally with conditionals as well - they would only save time if the processor is prepared to grab the sign bit for them. & what do you mean, "smooth folding"? Folding is necessarily a sharp, discontinuous operation; Tglad designed the formula to keep it from ripping already. If you want to express it with some analytic function, you mean, you could always use something with hyperbolas, like

y=sqrt(a+(x+1)^2)-sqrt(a+(x-1)^2)-x

for a something like 0.05. Would actually be fun to try playing around with the Mandelbox for different values of a, see what shapes you get.


Title: Re: A Mandelbox distance estimate formula
Post by: David Makin on April 04, 2010, 04:15:13 AM

Do using those functions save any time? I know that, in general, functions are kind of slow to be called. For most, I bet they're handled internally with conditionals as well - they would only save time if the processor is prepared to grab the sign bit for them

Knighty posted the alternative coding to avoid conditionals because conditionals are not friendly when it comes to GPU implimentation - on the GPU the method he suggested should be considerably faster I think (I can't check myself as I still don't have an appropriate video card installed).


Title: Re: A Mandelbox distance estimate formula
Post by: knighty on April 04, 2010, 09:52:17 PM
I've just done some tests on my crap GeForce 8400. It turns out that the "optimisations" I've suggested to Sublue are in fact slower  :'(.

Some renderings :embarrass::
On cpu:
(http://www.fractalforums.com/gallery/2/932_04_04_10_10_31_28.jpeg)

On GPU:
(http://www.fractalforums.com/gallery/2/932_04_04_10_10_45_58.jpeg)


Title: Re: A Mandelbox distance estimate formula
Post by: Hamilton on May 12, 2010, 12:51:59 PM
Ok, my turn to try out buddhi's DE tip...   :dink:
As you may guess, I used my own monte carlo raytracing renderer to get the attached image (mandelbox with scale -1.75) featuring HDR Image Based Lighting, Cook-Torrance BRDF for surface shading and adaptive antialiasing.
Still have to improve a few things and implement additionnal BRDF/BSDF to simulate more materials...


Title: Re: A Mandelbox distance estimate formula
Post by: KRAFTWERK on May 12, 2010, 01:28:16 PM
Very nice image mr Hamilton!


Title: Re: A Mandelbox distance estimate formula
Post by: knighty on May 12, 2010, 10:12:50 PM
Wow! superbe!


Title: Re: A Mandelbox distance estimate formula
Post by: Rrrola on September 10, 2010, 04:29:42 AM
I'm using knighty's formula with the following GPU optimizations (fR2 is fixed to one):
  // precomputed somewhere
  vec4 scalevec = vec4(SCALE, SCALE, SCALE, abs(SCALE)) / MR2;
  float C1 = abs(SCALE-1.0), C2 = pow(abs(SCALE), float(1-iters));

  // distance estimate
  vec4 p = vec4(position.xyz, 1.0), p0 = vec4(position.xyz, 1.0);  // p.w is knighty's DEfactor
  for (int i=0; i<iters; i++) {
    p.xyz = clamp(p.xyz, -1.0, 1.0) * 2.0 - p.xyz;  // box fold: min3, max3, mad3
    float r2 = dot(p.xyz, p.xyz);  // dp3
    p.xyzw *= clamp(max(MR2/r2, MR2), 0.0, 1.0);  // sphere fold: div1, max1.sat, mul4
    p.xyzw = p*scalevec + p0;  // mad4
  }
  return (length(p.xyz) - C1) / p.w - C2;
This is fast because min, max and mad(multiply-add) are fast no-branching operations and output saturation (clamping between 0 and 1) is free. Making iters a constant unrolls the loop for another speedup.

I've found that the formula also works when p0.xyz≠position (e.g. for julias or various transformations/foldings) as long as you keep p0.w=1.

Alternative box folds (may be faster on some architectures):
    p.xyz = clamp(p.xyz *0.5+0.5, 0.0, 1.0) *4.0-2.0 - p.xyz;  // mad.sat, mad, add

    p.xyz = abs(1.0+p.xyz) - p.xyz - abs(1.0-p.xyz);  // add, add, abs.add, abs.add


Title: Re: A Mandelbox distance estimate formula
Post by: knighty on September 10, 2010, 09:27:44 PM
Thank you for these valuable informations :)

I'm using knighty's formula
Acutally it's Buddhi's formula.:) I've just modified it a little bit. I think it can be improved further.
BTW! the statment:
distance = (sqrt(x*x+y*y+z*z)-abs(scale-1))/abs(DEfactor) - abs(scale)^(1-i);
is over complicated. Now i do instead:
distance = (sqrt(x*x+y*y+z*z)-BVR)/abs(DEfactor)
BVR is the radius of the bounding volume of the fractal.

It's possible to use max(max(abs(x),abs(y)),abs(z)) as the norm instead of sqrt(x*x+y*y+z*z). This is not an optimization, just another way to do it.
In case you are interrested, it's also possible to keep the size of the (positive scale) mandelbox constant.link (http://www.fractalforums.com/3d-fractal-generation/mandelbox-size/).



Title: Re: A Mandelbox distance estimate formula
Post by: Teraflop on November 06, 2010, 05:53:40 PM
Hm, nice... this "-BVR" makes a subtle but still visible improvement. Overall, I discovered, that sometimes you can multiply the distance estimation by some number above 1 and it will still work (typically somewhere between 1.5 and 2.5), but in some unusual cases, numbers below 1 are required.


Title: Re: A Mandelbox distance estimate formula
Post by: knighty on September 07, 2011, 02:38:02 PM
Overall, I discovered, that sometimes you can multiply the distance estimation by some number above 1 and it will still work (typically somewhere between 1.5 and 2.5), but in some unusual cases, numbers below 1 are required.
I guess that happens with positive scale Mandelboxes. I've finally found a tweek to "improve" their DE estimate:
Replace:
Code:
DEfactor = DEfactor * abs(scale) + 1.0;
by
Code:
DEfactor = -DEfactor * scale + 1.0;

This way, it's not necessary (AFAIK) to scale down the DE for negative scales. Unfortunately, this is not true with positive scales. There are areas where it's necessary to downscale the DE by a factor down to 0.45 or so... Something is still missing. :sad1: