Welcome to Fractal Forums

Fractal Software => Programming => Topic started by: tryptophan on April 04, 2013, 06:19:50 AM




Title: Is there a way to maintain a real distance field when modifying this fragment?
Post by: tryptophan on April 04, 2013, 06:19:50 AM
I've been by using some of the tools on the Iñigo Quílez's site incorportating them into some of the fractal formulas. I've successfully been able to replicate a Kaleidoscopic IFS octahedral to infinti along all three axis using a simple modulus equation. I'm having a problem though when I tried to do rotation or transformations within the iteration where the field no longer seems to be a real Distance Field (I think I am using the right terminology). Is there a way to keep the distance function true with this approach? Below is my code and some images if anyone would like to take a look. Please don't mind some of the variable names I'm using a bank of predefined sliders/uniforms for some of the variables.

Code:
float octahedron( vec3 z,mat3 rot1, vec3 offset, mat3 rot2, float scale, int iter, int colIter, float cScale, float cOffset)
{
float r;

// Iterate to compute the distance estimator.
int n = 0;
while (n < iter) {
//z *= rot1;

if (z.x+z.y<0.0) z.xy = -z.yx;
if (z.x+z.z<0.0) z.xz = -z.zx;
if (z.x-z.y<0.0) z.xy = z.yx;
if (z.x-z.z<0.0) z.xz = z.zx;

z = (z*scale - offset*(scale-1.0));
//z *= rot2;

r = dot(z, z);
            if (n< colIter)  orbitTrap = min(orbitTrap, abs(vec4(z,r)));
            

n++;
}
orbitTrap*= cScale+ cOffset;
return (length(z) ) * pow(scale, -float(n));
}

void init()
{
rot2 = rotationMatrix3(normalize(Rotate2.xyz),Rotate2.w);
rot1 = rotationMatrix3(normalize(Rotate1.xyz),Rotate1.w);
fullRotate = rotationMatrixXYZ(Rotate);
}


float shape(vec3 p)
{
if (object1 == 0) return sdSphere(p,Offset.x*.05);
else if (object1 == 1) return sdBox(p,Offset*.05);
else if (object1 == 2) return udRoundBox( p, Offset*.05, Scale*.01);
else if (object1 == 4) return octahedron( p, rot1, Offset , rot2, Scale, Iterations,
ColorIterations, ColorScale, ColorOffset);
else if (object1 == 5) return sdCross(p, Offset.xyz*.05);
else if (object1 == 6) return sdCross2(p, Offset.xyz*.05, Scale*.01);
else if (object1 == 7) return sdCross3(p, Offset.xyz*.05);
else return sdSphere(p,Offset.x*.1);
}

float opRep( vec3 p, vec3 c)
{
vec3 p2 = p;
if (Fold.w == 0) p2 =p;
else if (Fold.w == 1)
{
p2.x = mod(p2.x,c.x)-.5*c.x;
}
else if (Fold.w == 2)
{
p2.xz = mod(p2.xz,c.xz)-.5*c.xz;
}
else if (Fold.w == 3)
{
p2.xy = mod(p2.xy,c.xy)-.5*c.xy;
}
else if (Fold.w == 4)
{
p2.zy = mod(p2.zy,c.zy)-.5*c.zy;
}
else if (Fold.w == 5)
{
p2 = mod(p2,c)-.5*c;
}
else p2 = p;
return shape(p2);


}

float DE(vec3 p)
{
p += Position;
p *= fullRotate;
return opRep(p,Fold.xyz*.1);

}


Title: Re: Is there a way to maitain a real distance field with this fragment?
Post by: tryptophan on April 04, 2013, 06:21:05 AM
Sorry the second image
thanks
Keith


Title: Re: Is there a way to maintain a real distance field when modifying this fragment?
Post by: eiffie on April 04, 2013, 05:36:26 PM
a plain mod is discontinuous and not really a fold so use a tiling instead - this is from Knighty if I remember correctly ...

vec3 Tile3D(vec3 p, float a){p+=vec3(a);p-=4.0*a*floor(p/(4.0*a));p-=2.0*max(p-2.0*a,0.0);return p-vec3(a);}
vec2 Tile2D(vec2 p, float a){p+=vec2(a);p-=4.0*a*floor(p/(4.0*a));p-=2.0*max(p-2.0*a,0.0);return p-vec2(a);}
float Tile1D(float p, float a){p+=a;p-=4.0*a*floor(p/(4.0*a));p-=2.0*max(p-2.0*a,0.0);return p-a;}


Title: Re: Is there a way to maintain a real distance field when modifying this fragment?
Post by: Syntopia on April 04, 2013, 09:52:31 PM
Yes, the mod function is discontinuous - a slightly simpler way to create the continuous triangle wave function above is by using:
Code:
z  = abs(A-mod(z,2.0*A));
where A is the cell spacing. Just insert the transformation at the top of the DE-function.

This makes rotating the octahedron possible:

(http://blog.hvidtfeldts.net/media/tile.jpg)


Title: Re: Is there a way to maintain a real distance field when modifying this fragment?
Post by: tryptophan on April 04, 2013, 10:19:31 PM
Awesome. Thanks for the tips guys. I'll try that right away. I know some of my questions are pretty basic, thanks for helping.

cheers
Keith


Title: Re: Is there a way to maintain a real distance field when modifying this fragment?
Post by: tryptophan on April 04, 2013, 10:42:17 PM
Okay so I've tried both methods and found both to have function slightly differently. I think I can learn use from both for different functions. They lead me to another question I already had from yesterday also.

With both the methods you guys posted the plane of repeated shapes ends abruptly. I seems you can only really see about 20 - 40 repetitions (depending one how close they are). I had the same problem with the equation I was using last night although it repeated further but still ended. In all three case I've cranked the Max Ray Steps and the Bounding Sphere parameters way up but they don't seem to have an effect after a certain  point.

Is there something I can change/add to the raytracer to solve this?

thanks
Keith
 


Title: Re: Is there a way to maintain a real distance field when modifying this fragment?
Post by: Syntopia on April 04, 2013, 10:57:58 PM
Okay so I've tried both methods and found both to have function slightly differently. I think I can learn use from both for different functions. They lead me to another question I already had from yesterday also.

With both the methods you guys posted the plane of repeated shapes ends abruptly. I seems you can only really see about 20 - 40 repetitions (depending one how close they are). I had the same problem with the equation I was using last night although it repeated further but still ended. In all three case I've cranked the Max Ray Steps and the Bounding Sphere parameters way up but they don't seem to have an effect after a certain  point.

Is there something I can change/add to the raytracer to solve this?

thanks
Keith
 

Try to search the raytracer code for a 'float MaxDistance =' definition and increase this value (yes, that really should be an uniform parameter!)


Title: Re: Is there a way to maintain a real distance field when modifying this fragment?
Post by: tryptophan on April 04, 2013, 11:02:14 PM
Sweet!!!!


Title: Re: Is there a way to maintain a real distance field when modifying this fragment?
Post by: cKleinhuis on April 04, 2013, 11:06:21 PM
and never forget the iteration depth ;)


Title: Re: Is there a way to maintain a real distance field when modifying this fragment?
Post by: Syntopia on April 04, 2013, 11:14:50 PM
Okay so I've tried both methods and found both to have function slightly differently. I think I can learn use from both for different functions. They lead me to another question I already had from yesterday also.

Yes, I tried plotting them and Eiffies code is slightly different offset. This code should get exactly the same:
Code:
p = abs(2.0*a-mod(p-vecX(a),a*4.0))-vecX(a);
(where vecX is the type of p) - but then the formula is less simple.