Welcome to Fractal Forums

Fractal Math, Chaos Theory & Research => (new) Theories & Research => Topic started by: Tglad on November 16, 2012, 07:00:23 AM




Title: New fractal.. needs a name
Post by: Tglad on November 16, 2012, 07:00:23 AM
I made this new fractal http://glsl.heroku.com/e#4851.17 (http://glsl.heroku.com/e#4851.17)
It is similar to this Koch surface:
(http://tartley.com/wp-content/uploads/2010/08/Koch_surface_0_through_3.png)
but you can pick how much it bends, as you can with a 2d Koch curve:
(http://www.generativeart.com/on/cic/papersga2004/15_file/image006.gif)

I need to optimise the code (any tips?) and fix a few pixel glitches. You'll need webGL on your browser to view it.
Thanks Syntopia for the Mandelbulb example for guidance.


Title: Re: New fractal.. needs a name
Post by: kram1032 on November 16, 2012, 08:58:33 AM
Koch-Peano-surface.
Maybe you can extend it further to be able to do a bit more:
http://en.wikipedia.org/wiki/De_Rham_curve


Title: Re: New fractal.. needs a name
Post by: Kali on November 16, 2012, 09:25:25 AM
I get "maximum temp register index exceeded" errors. I have a Radeon 6870, tried with Firefox and Chrome.


Title: Re: New fractal.. needs a name
Post by: KRAFTWERK on November 16, 2012, 10:58:44 AM
TetraGlad-Koch


Title: Re: New fractal.. needs a name
Post by: visual.bermarte on November 16, 2012, 02:00:42 PM
@Kali: maybe it's an ANGLE problem; see http://blog.hvidtfeldts.net/index.php/2012/06/webgl-for-shader-graphics/ or http://www.fractalforums.com/fractal-programs/new-webgl-application-to-explore-3d-fractals/
Firefox and Chrome use ANGLE by default.
In Firefox use the about:config URL, .. set webgl.prefer-native-gl=true to disable ANGLE.
For the other browser, just make a shortcut to Chrome with the --use-gl=desktop key.


Title: Re: New fractal.. needs a name
Post by: DarkBeam on November 16, 2012, 05:53:23 PM
It says compiled with errors. And nothing is displayed, here :fiery:

EDIT:

This is the script for those who are interested

Code:
#ifdef GL_ES
precision highp float;
#endif

// Fractal surface - by Thomas Lowe
// Some code based on Mandelbulb example by Syntopia
const int maxIterations = 6;
#define VIEW_FULL_TRIANGLE 0
#define SHADOWS_ENABLED 1
const float shadowStrength = 0.8;

#define REVERSE_TRI0 0
#define REVERSE_TRI1 0
#define REVERSE_TRI2 0
#define REVERSE_TRI3 0
#define REVERSE_TRI4 0
#define REVERSE_TRI5 0

uniform vec2 resolution;
uniform float time;
uniform vec2 mouse;
uniform sampler2D backbuffer;

float PI=3.14159265;
float angle = 0.0;
float height = 0.0;

const int numSegments = 6;
vec3 centres[numSegments];
vec3 segmentOffsets[numSegments];
float segmentScales[numSegments];
mat3 rotations[numSegments];
vec3 corners[3];

// Compute the distance from `pos` to the surface
float DE(vec3 pos) {
vec3 middle = vec3(segmentOffsets[0][0], 0, segmentOffsets[0][2]);
pos += middle;
float totalScale = 1.0;
for (int it = 0; it<maxIterations; it++)
{
// find closest
mat3 rotation = rotations[0];
vec3 offset = segmentOffsets[0];
float scale = segmentScales[0];
vec3 toPos = pos - centres[0];
float closest = dot(toPos, toPos);
for (int i = 1; i<numSegments; i++)
{
vec3 to = pos - centres[i];
float dt = dot(to, to);
#if VIEW_FULL_TRIANGLE==1
if (dt < closest)
#else
if (dt < closest && (it>0 || i<4))
#endif
{
closest = dt;
rotation = rotations[i];
offset = segmentOffsets[i];
scale = segmentScales[i];
}
}
pos -= offset;
pos = pos * rotation;
totalScale *= scale;
/* vec3 dif = pos - middle;
float blah = dot(dif, dif);
if (blah > 3.0)
break;*/
}

vec3 normal = normalize(cross(corners[2]-corners[0], corners[1] - corners[0]));
float h = dot(pos - corners[0], normal);
vec3 onPlane = pos - normal * h;
vec3 lines[3];
lines[0] = corners[1] - corners[0]; lines[1] = corners[2] - corners[1]; lines[2] = corners[0] - corners[2];
for (int i = 0; i<3; i++)
{
vec3 dif = onPlane - corners[i];
vec3 norm = cross(normal, lines[i]);
float dist = dot(dif, norm) / dot(norm, norm);
if (dist > 0.0)
{
onPlane -= norm * dist;
float along = dot(dif, lines[i]) / dot(lines[i], lines[i]);
if (along < 0.0)
onPlane -= lines[i] * along;
else if (along > 1.0)
onPlane -= lines[i] * (along - 1.0);
break;
}
}
return length(onPlane - pos) / totalScale;
}
#if SHADOWS_ENABLED==1
// Uses the soft-shadow approach by Quilez:
// http://iquilezles.org/www/articles/rmshadows/rmshadows.htm
float shadow(vec3 pos, vec3 sdir, float eps) {
float totalDist =2.0*eps;
float s = 1.0; // where 1.0 means no shadow!
for (int steps=0; steps<30; steps++) {
vec3 p = pos + totalDist * sdir;
float dist = DE(p);
if (dist < eps)  return 1.0;
s = min(s, 4.0*(dist/totalDist));
totalDist += dist;
}
return 1.0-s;
}
#endif


void calculateSegments()
{
  height = 2.3*(mouse.y - 0.5); // -1 to 1 about
float limit = 0.6;
if (height > limit)
height = limit;
else if (height < -limit)
height = -limit;
        angle = PI/2.0;
for (int i = 0; i<5; i++)
{
float cosa = cos(angle);
float sina = sin(angle);
float denom = 1.0/(4.0*height*height + sina*sina);
angle = atan(sqrt((1.0 + 2.0*cosa + cosa*cosa) * denom)) + atan(sqrt((1.0 - 2.0*cosa + cosa*cosa)*denom));
}
// we assume corner0 is 0,0 corner1 is 1,0, corner2 is sin(bendAngle),cos(bendAngle)
// these are corners of the parallelegram, so corner3 is corner1+corner2
float cosa = cos(angle);
float sina = sin(angle);
vec3 x = vec3(1,0,0);
vec3 z = vec3(cosa, 0, sina);
vec3 end = x + z;
vec3 top = end*0.5 + vec3(0, height, 0);
segmentOffsets[0] = segmentOffsets[1] = segmentOffsets[2] = segmentOffsets[3] = top;
segmentOffsets[4] = z;
segmentOffsets[5] = x;
centres[0] = (x + top)/3.0;
centres[1] = (z + top)/3.0;
centres[2] = (x + top + end)/3.0;
centres[3] = (z + top + end)/3.0;
float sideLengthC = length(top);
float sideLengthB = length(vec3(1,0,0) - top);
float scale = 1.0/sideLengthC + 1.0/sideLengthB;
segmentScales[0] = segmentScales[1] = segmentScales[2] = segmentScales[3] = scale;
segmentScales[4] = sideLengthB*scale;
segmentScales[5] = sideLengthC*scale;
corners[0] = vec3(0,0,0);
corners[1] = x * (1.0 + sideLengthB / sideLengthC);
corners[2] = z * (1.0 + sideLengthC / sideLengthB);

// now I need to work out the rotation matrices for each segment
rotations[0][0] = normalize(x - top);
rotations[0][1] = -normalize(cross(rotations[0][0], top));
rotations[0][2] = -cross(rotations[0][0], rotations[0][1]);
rotations[1][0] = normalize(z - top);
rotations[1][1] = normalize(cross(rotations[1][0], top));
rotations[1][2] = cross(rotations[1][0], rotations[1][1]);

rotations[2][0] = rotations[0][0];
rotations[2][1] = normalize(cross(rotations[2][0], top-end));
rotations[2][2] = cross(rotations[2][0], rotations[2][1]);
rotations[3][0] = rotations[1][0];
rotations[3][1] = -normalize(cross(rotations[3][0], top-end));
rotations[3][2] = -cross(rotations[3][0], rotations[3][1]);
rotations[0] *= segmentScales[0];
rotations[1] *= segmentScales[1];
rotations[2] *= segmentScales[2];
rotations[3] *= segmentScales[3];

rotations[4] = mat3(segmentScales[4]);
rotations[5] = mat3(segmentScales[5]);
#if REVERSE_TRI0==1
rotations[0][1] *= -1.0;
#endif
#if REVERSE_TRI1==1
rotations[1][1] *= -1.0;
#endif
#if REVERSE_TRI2==1
rotations[2][1] *= -1.0;
#endif
#if REVERSE_TRI3==1
rotations[3][1] *= -1.0;
#endif
#if REVERSE_TRI4==1
rotations[4][1] *= -1.0;
#endif
#if REVERSE_TRI5==1
rotations[5][1] *= -1.0;
#endif

// lastly, work out the centres for 4 and 5, this should be optimised for biggest range of height
vec3 norm = cross(end-x, vec3(0,1,0)); // modify this up vector for variation
centres[5] = centres[2] + 2.0 * norm * dot(norm, x - centres[2])/dot(norm, norm);
norm = cross(end-z, vec3(0,1,0));
centres[4] = centres[3] + 2.0 * norm * dot(norm, z - centres[3])/dot(norm, norm);    
}

void main(void){
calculateSegments();
vec2 vPos=0.5*(-1.0+2.0*gl_FragCoord.xy/resolution.xy);

float t = 0.2*time;
if (height < 0.0)
t += PI/2.0;
float sinA = sin(t);
float cosA = cos(t);
mat3 bearing = mat3(vec3(cosA, 0, sinA), vec3(0,1,0), vec3(-sinA, 0, cosA));

//Camera animation
vec3 vuv=vec3(0,1,0);//Change camere up vector here
vec3 vrp=vec3(0,0,0); //Change camere view here
float mx=0.0;
float my=0.5*PI/2.01;
vec3 prp=bearing * vec3(cos(my),sin(my),0.0)*2.0; //Trackball style camera pos


//Camera setup
vec3 vpn=normalize(vrp-prp);
vec3 u=normalize(cross(vuv,vpn));
vec3 v=cross(vpn,u);
vec3 vcv=(prp+vpn);
vec3 scrCoord=vcv+vPos.x*u*resolution.x/resolution.y+vPos.y*v;
vec3 scp=normalize(scrCoord-prp);

//Raymarching
const vec3 e=vec3(0.000001,0,0);
const float maxd=3.0; //Max depth
float s=0.0;
vec3 c,p,n;

float f=0.80;

for(int i=0;i<46;i++){
f+=s*0.8;
p=prp+scp*f;
s=DE(p);
if (s<.00065||f>maxd)
break;
}


if (f<maxd){
n=normalize(
vec3(s-DE(p-e.xyy),
s-DE(p-e.yxy),
s-DE(p-e.yyx)));

//c.yz = mix(c.yz, n.yz, 0.3);
vec3 dir = normalize(prp-p);
vec3 spotDir = bearing * normalize(vec3(-1.0,-2.0,1.5));
// Calculate perfectly reflected light
vec3 r = spotDir - 2.0 * dot(n, spotDir) * n;
float s = max(0.0,dot(dir,-r));
float diffuse = max(0.0,dot(-n,spotDir))*0.60;
float ambient =1.0;
float specular = 0.0;//clamp(pow(s,50.0)*1.1,0.0,0.5);
#if SHADOWS_ENABLED==1
float eps = 0.001;
if (shadowStrength>0.0) {
// check path from pos to spotDir
float strength = shadow(p+n*eps, -spotDir, eps);
ambient = mix(ambient,0.0,shadowStrength*strength);
diffuse = mix(diffuse,0.0,shadowStrength*strength);
if (strength>0.0)
specular = 0.0; // always turn off specular, if blocked
}
#endif
gl_FragColor=vec4((vec3(1.0)*diffuse+vec3(1.0)*ambient+ specular*vec3(1.0))*vec3(0.5),1.0);
}
}


Title: Re: New fractal.. needs a name
Post by: Tglad on November 17, 2012, 12:16:52 AM
I guess webGL isn't so portable after all  :-\
To see how the fractal is built you can set SHOW_FULL_TRIANGLE to 1 in the code, and set the maxIterations to 0, then 1, then 2 etc. Basically each triangle becomes six identical but smaller triangles including 4 in a squashed pyramid shape. For a pyramid base edge length of 1, you define the shape based on the pyramid height:
<0 shell shape
=0 flat plane
>0 tree shape
0.55 (roughly) max height without self penetration. i.e. tree-sponge (see https://sites.google.com/site/simplextable/what-is-the-simplex-table)
1.75 (roughly) singular point where children are same size as parent triangle so shape is infinite in size and probably fully covers the space.

(In the example the height only goes from -0.7 to 0.7 as you move the mouse up and down).


Title: Re: New fractal.. needs a name
Post by: Syntopia on November 17, 2012, 09:22:42 AM
I tried the fractal, and it is yet another ANGLE issue. It works fine under Chrome and Firefox with ANGLE disabled. With ANGLE disabled I get the same error as Kali. Opera fails for other reasons.

WebGL is a great technology, but as of now it is so broken. Apple refuse to officially support it on their iOS devices (even though they use it in their iAds), Microsoft refuse to use it in IE for security reasons, and Chrome and Firefox's reliance on ANGLE means the nearly all complex shaders fail.


Title: Re: New fractal.. needs a name
Post by: Pauldelbrot on November 18, 2012, 12:36:34 AM
Microsoft refuse to use it in IE for security reasons

Is that a joke, or a sign of the impending Apocalypse?


Title: Re: New fractal.. needs a name
Post by: rollercoaster158 on November 18, 2012, 04:36:22 AM
Is that a joke, or a sign of the impending Apocalypse?

Actually a sign of the impending Windows 8, but that's basically the same as the apocalypse.

Yeah, getting "Compiled with errors" on all browsers.  :-\


Title: Re: New fractal.. needs a name
Post by: kram1032 on November 18, 2012, 11:35:58 AM
oh wow, I only now saw the link to the website and see what you're talking about.
Yeah, "compiled with errors" on Firefox.
Makes me wonder, how did you even make it work for yourself? What browser are you using?


Title: Re: New fractal.. needs a name
Post by: Tglad on November 18, 2012, 06:29:18 PM
I'm on a macbook, it works fine in Chrome and Firefox.
I'll try converting it to Fragmentarium at some point... or if anyone is game you can hover over the 'compiled with errors' text and it will tell you the error... maybe it is just a small syntax thing.


Title: Re: New fractal.. needs a name
Post by: kram1032 on November 18, 2012, 06:45:16 PM
Win7 Firefox 16.0.2
(http://puu.sh/1rCDT)


Title: Re: New fractal.. needs a name
Post by: Tglad on November 18, 2012, 07:39:30 PM
Same as Kali, looks like your graphics cards don't have enough temporary registers in them to perform the code.
Not simple to fix, just too many variables for your card.


Title: Re: New fractal.. needs a name
Post by: Syntopia on November 18, 2012, 08:56:46 PM
Same as Kali, looks like your graphics cards don't have enough temporary registers in them to perform the code.
Not simple to fix, just too many variables for your card.

No, this is an ANGLE problem. I get the same error - but if I disable ANGLE it works - both in Firefox and Chrome. This is Windows issue only, since there is no GLSL->HSLSL conversion on Mac.

For unknown reasons ANGLE imposes shader model 3 constraints, which has only 32 temporary registers.


Title: Re: New fractal.. Volcanic Surface
Post by: Tglad on November 28, 2012, 01:44:28 PM
Thanks Syntopia, useful info.
Here you can see the surface with height of -0.25 up to 1:
(http://2.bp.blogspot.com/-LizyprvPr-A/ULYDG0h0_rI/AAAAAAAAAMc/HpTQDgFCw8U/s640/surface.png)

It really explodes out like a volcano when height increases past 1, so I think I'll call it a volcanic surface fractal.
Around 1.75 the fractal occupies all of space and has a Hausdorff dimension of infinity!


Title: Re: New fractal.. needs a name
Post by: cKleinhuis on November 28, 2012, 02:11:01 PM
infinite hausdorff dimension ? please elaborate!


Title: Re: New fractal.. needs a name
Post by: DarkBeam on November 28, 2012, 05:21:23 PM
Works - managed to disable that ANGLE! :-X


Title: Re: New fractal.. needs a name
Post by: kram1032 on November 28, 2012, 09:56:43 PM
There's mathematically no way it could have a Hausdorff dimension above 3. - unless you embed the entire thing in higher-dimensional space. - particularly in infinite-dimensional one.
Besides that, it's really nice stuff.

If you somehow calculate the Hausdorff Dimension with some sort of algorithm and you get infinity, that's either because of numerical instabilities or your algorithm is wrong.


Title: Re: New fractal.. Volcanic Surface
Post by: Tglad on November 28, 2012, 11:05:22 PM
It is because there is overlap (for height > 0.55), so some points in space have double cover, or triple cover etc. You can do the same thing with the Levy C curve, for 90 degree bend angle it has Hausdorff dimension 2 (log(2) / log(sqrt(2))), for bend angle > 90 degree it is log(2)/log( < sqrt(2) ) so the dimension is > 2.
If you don't allow multi-cover of the space then the max Hausdorff dimension is the dimension of the space.

Here's a higher res of above image:
(http://2.bp.blogspot.com/-LizyprvPr-A/ULYDG0h0_rI/AAAAAAAAAMc/HpTQDgFCw8U/s1600/surface.png)


Title: Re: New fractal.. needs a name
Post by: kram1032 on November 29, 2012, 12:10:56 AM
ah, so multiple-covering counts for adding dimensions. That sort of makes sense. It's like you need more space than you actually have, so you multi-cover to get there.


Title: Re: New fractal.. needs a name
Post by: cKleinhuis on November 29, 2012, 12:56:18 AM
i get this, but in my eyes it is not really special, because such curves exists ... basically the trivial curve with no movement ... the dot at the center of the c oordinate system would have as well unlimited hausdorff dimension

this brings us to the space filling curves and why it is such a good name ;) but as far as i know the definition of space filling curves is NOT limited to the topografical dimension !?


Title: Re: New fractal.. needs a name
Post by: Tglad on November 29, 2012, 09:45:51 AM
I agree, higher dimension from overlap is a bit meaningless. If we don't allow multi-cover of the space then this fractal goes from 2d and approaches 3d as height goes from 0 to about 1.75. We'd also have to accept that Levy C curve has Hausdorff dimension a little less than 2.

Here are the first 3 iterations if you hadn't guessed:
(http://3.bp.blogspot.com/-XGlu2gZRW5U/ULcfI2P4EwI/AAAAAAAAAMs/OWGp1UbQFzI/s1600/iterations.png)


Title: Re: New fractal.. needs a name
Post by: kram1032 on November 29, 2012, 11:32:16 AM
that iteration looks pretty wild. nice.


Title: Re: New fractal.. needs a name
Post by: Tglad on December 01, 2012, 01:39:05 AM
Here's a variation, you reverse the face normal of the 6 sub-triangles, it gives a shape that looks the same from both sides of the surface:
(http://1.bp.blogspot.com/-LFmselDmYgk/ULlM9zN316I/AAAAAAAAAM8/oMT941lbgJA/s1600/funny11.png)
(http://4.bp.blogspot.com/-QulPiZutT78/ULlM_gdbOBI/AAAAAAAAANE/ou_DtFmwizg/s1600/funny12.png)
(http://4.bp.blogspot.com/-XirFbCKjfMA/ULlNBkjb05I/AAAAAAAAANM/Ekto6iydPu4/s1600/nice1.png)
So is a bit like how the Koch curve differs from the Levy C curve.
The pics are the largest height without self intersection, about 0.35.

Here's a challenge that is open to everyone... 
ready?...

is there a fractal like this that doesn't self-intersect but folds up into a space-filling surface like the Von Koch curve does?


Title: Re: New fractal.. needs a name
Post by: Tglad on December 11, 2012, 11:16:14 PM
There's an interesting critical point, when the height is 0.55209 then all the triangles are isosceles. This is also about the point where the shape is at its most rough without self-intersecting. I'm not sure if those two are exactly the same point but they could well be.


Title: Re: New fractal.. needs a name
Post by: kram1032 on December 12, 2012, 12:48:51 AM
it's pretty likely that they are.
Would be a strange rare math stunt if they weren't.