# Fractalforums

## Fractal Software => Programming => Topic started by: chantecleer on October 12, 2019, 03:17:20 AM

Title: Calculating hybrid formulas in GLSL to match Mandelbulb3D
Post by: chantecleer on October 12, 2019, 03:17:20 AM
Hi everyone! I am trying to match the graphical output of Mandelbulb3D with a GLSL shader, for a hybrid fractal (for the sake of learning all the ins and outs). Let's say I have 12 iterations of Amazing Box in formula 1, and 1 iteration of Folding Int Pow in formula 2. This should produce Kleinian drops, such as the ones by Theli-at.

Now I have a standard raymarcher in GLSL with two Distance Estimators, one for AmazingBox and one for Folding Int Pow. They both take in a vec3 (position) and return a float (distance) to the respective object.

How does one go about combining these DEs to create hybrid objects? Or, I suppose more to the point, how does Mandelbulb3D alternate its formulas in this approach. My only idea is to modify the functions to take a position and direction vector, and return a new position, but that doesn't seem to be the way others have implemented hybrids.

I hope someone can enlighten me on this topics  :embarrass: :D
Title: Re: Calculating hybrid formulas in GLSL to match Mandelbulb3D
Post by: mclarekin on October 12, 2019, 09:08:17 AM
Try this
https://fractalforums.org/fragmentarium/17/boxbulb/2391 (https://fractalforums.org/fragmentarium/17/boxbulb/2391)

There are actually three ways that I do the DE for boxBulbs and it is still a "work in progress"
Title: Re: Calculating hybrid formulas in GLSL to match Mandelbulb3D
Post by: chantecleer on October 13, 2019, 11:03:56 PM
Thanks, so this one uses formulas for two fractals within the loop. There are also hybrids that separate the loops for each fractal, one loop beginning after the other, such as in Knighty's PseudoKleinianMenger.frag example in Fragmentarium. I suppose this is what makes making hybrids a black art...
Title: Re: Calculating hybrid formulas in GLSL to match Mandelbulb3D
Post by: mclarekin on October 14, 2019, 02:51:02 AM
One loop is simply because that is how i code it for implementation in MandelbulberV2.  Coding the different fractals and transforms as inline functions  is probably the best way.

The DE for this type of hybrid is tricky maily due to the z.z scale. Normally when hybridizing linearDE type fractals with logDE type fractals just use standard logDE, but occasionally you need to use linearDE. In Fragmentarium GLSL it is easy to add an option for both and test the results.
Title: Re: Calculating hybrid formulas in GLSL to match Mandelbulb3D
Post by: chantecleer on October 15, 2019, 02:48:02 AM
The DE for this type of hybrid is tricky maily due to the z.z scale. Normally when hybridizing linearDE type fractals with logDE type fractals just use standard logDE, but occasionally you need to use linearDE.

By logDE are you referring to the specific DE formulas that work for Mandelbulb / Mandelbox? I implemented a simple starter hybrid from a tetrahedron and a menger, and it is already getting the "bad DE ripples" at iteration 4, no matter what alterations to the distance get done, or even decreasing the ray step by 0.5 :( does this have to do something with the fact that z is scaled by 2, then translated, then scaled by 3, then translated again?

the code is:

float map(vec3 z)
{
// tetrahedron consts
vec3 TetraOffset = vec3(1.0);
float TetraScale = 2.0;//+sin(iTime);

// menger consts
vec3 MengerOffset = vec3(1.0);
float MengerScale = 3.0;// + sin(iTime);
float d = 1000.0;

// shared consts
int Iterations = 4;
int n = 0;
float total_scale = 1.0;
while (n < Iterations)
{
// Tetrahedron step
if(z.x+z.y<0.) z.xy = -z.yx; // fold 1
if(z.x+z.z<0.) z.xz = -z.zx; // fold 2
if(z.y+z.z<0.) z.zy = -z.yz; // fold 3
z = z*TetraScale - TetraOffset*(TetraScale-1.0);

// Menger step
//z=MnScale* (z-MnOffset)+MnOffset; // weird
z = abs(z);
z = z*MengerScale - MengerOffset*(MengerScale-1.0);
if (z.x<z.y){ z.xy = z.yx;}
if (z.x< z.z){ z.xz = z.zx;}
if (z.y<z.z){ z.yz = z.zy;}
if( z.z<-0.5*MengerOffset.z*(MengerScale-1.0))
{
z.z+=MengerOffset.z*(MengerScale-1.0);
}
d = min(d, length(z) * pow(TetraScale * MengerScale, float(-n)-1.0));

// shared
n++;
total_scale = total_scale * TetraScale * MengerScale;
}
float TetraReturn = (length(z)) / (total_scale); // experimental DEs for returning
float MengerReturn = d - 0.001;
float ret = (length(z)-1.) / (total_scale+1.0);

return MengerReturn;//min(MengerReturn, TetraReturn);
}
Title: Re: Calculating hybrid formulas in GLSL to match Mandelbulb3D
Post by: mclarekin on October 16, 2019, 12:24:44 AM
There are a lot of fractals that use a "standard" type of DE

typical log DE   (power functions, "bulbs") which have a final calculation  :    return 0.5 * log(r) * r / dr;
typical linear DE   (scale functions, "IFS , boxes") which have a final calculation  :    return  r / dr;

In this example you are combining two linear.

Here note how the DE calculation in the .Fragmentarium code has been rewritten to make it clearer

Code: [Select]
// The fractal distance estimation calculationfloat DE(vec3 z){ float rr; // r squared float dr = 1.0; // Iterate to compute the distance estimator. int n = 0; while (n < Iterations) { z *= fracRotation1; if(z.x+z.y<0.0) z.xy = -z.yx; if(z.x+z.z<0.0) z.xz = -z.zx; if(z.y+z.z<0.0)z.zy = -z.yz; z = z*Scale - Offset*(Scale-1.0); dr *= Scale; z *= fracRotation2; rr = dot(z, z); if (n< ColorIterations)  orbitTrap = min(orbitTrap, abs(vec4(z,rr))); n++; } return sqrt(rr) / abs(dr); }