Welcome to Fractal Forums

Fractal Software => Programming => Topic started by: Deliverance on February 26, 2011, 07:46:47 PM




Title: I'm new! Mandelbulb & IFS's
Post by: Deliverance on February 26, 2011, 07:46:47 PM
Hi guys! I'm new here here so a big hello to everyone!

Now, let's go straight into the business. Yesterday i started my adventures into exploring the mandelbulb. Obviously i ran into some problems. First there is the speed: i'm ray marching constant steps and iterate over the formulas to see if i'm inside or not. How can this be improved?

Second there is coloring: i managed to get normals but it looks kind of dull with phong shading and ramp coloring. How can i do better?

Here are two pictures of the beast:
http://img8.imageshack.us/i/mandelbulbimg2.png/ (http://img8.imageshack.us/i/mandelbulbimg2.png/)
http://img156.imageshack.us/i/mandelbulbimg.png/ (http://img156.imageshack.us/i/mandelbulbimg.png/)

And here is the GLSL shader code, for reference:
Code:
varying vec3 position;
uniform float time;
uniform sampler2D spectrum;
int maxiter = 6;

vec4 getMandelbrot(vec3 posInit)
{
posInit *= 1.95;

//posInit.x -= 1.15;
//posInit /= 2.0;

vec3 pos = posInit;
int n = 8;
int i;

for (i=0; i<4; i++)
{
float r = length(pos);

if (r > 2.0)
return vec4(pos, 0.0);

float theta = atan2(length(pos.xy), pos.z);
float phi = atan2(pos.y, pos.x);

float pown = pow(float(r), float(n));

pos.x = pown * sin(theta*n) * cos(phi*n);
pos.y = pown * sin(theta*n) * sin(phi*n);
pos.z = pown * cos(theta*n);

pos += posInit;
}

return vec4(pos, 1.0);
}

vec3 rotateX(vec3 pos, float angle)
{
vec3 ret;
ret.x = pos.x;

ret.y = cos(angle)*pos.y - sin(angle)*pos.z;
ret.z = sin(angle)*pos.y + cos(angle)*pos.z;

return ret;
}
int numIterations = 128;
vec4 marchRayMandelbrot(vec3 pos)
{
int i = 0;
vec3 dir = vec3(0.0, 0.0, 2.0);

float angle = time / 8;

dir = rotateX(dir, angle);
pos = rotateX(pos, angle);

vec3 inc = 1.0 / float(numIterations) * dir;
vec3 start = pos;
vec3 end = pos+dir;

for (i=0; i<numIterations; i++)
{
vec4 a = getMandelbrot(pos);
if (a.w != 0.0)
{
a.w = i;
return a;
}
pos += inc;
}

return vec4(0.0,0.0,0.0,0.0);
}

void main()
{
float eps = 0.01;
gl_FragColor = 0.0;
vec3 lightPos = vec3(0.0,0.0,10.0);

vec4 a = marchRayMandelbrot(position);

if (a.w > 0.0)
{
float len = length(a.xyz);

vec4 a1 = marchRayMandelbrot(position + vec3(eps, 0.0, 0.0)) - marchRayMandelbrot(position - vec3(eps, 0.0, 0.0));
vec4 a2 = marchRayMandelbrot(position + vec3(0.0, eps, 0.0)) - marchRayMandelbrot(position - vec3(0.0, eps, 0.0));
vec4 a3 = marchRayMandelbrot(position + vec3(0.0, 0.0, eps)) - marchRayMandelbrot(position - vec3(0.0, 0.0, eps));

a1 /= 2*eps;
a2 /= 2*eps;
a3 /= 2*eps;

vec3 norm = vec3(length(a1.xyz),
length(a2.xyz),
length(a3.xyz));

norm = normalize(norm);

vec3 lightDir = normalize(lightPos - a.xyz);
vec3 view = -normalize(a.xyz);
float diff = 0.35+0.5*max(0.0, dot(norm, lightDir));

float spec = 0.0;
if (diff > 0.0)
{
spec = max(0.0, pow(dot(normalize(lightDir+view), norm), 64.0));
}

//gl_FragColor = vec4(0.0, 1.0, 0.0, 0.0)*diff*0.8+spec;
gl_FragColor = spec + diff*texture2D(spectrum, vec2(a.w / numIterations, 0.0));
//gl_FragColor = 1.0;
}

}

And third there are IFS's. Where can i get some starting functions that would produce nice images? I managed to display the sierpiensky triangle but nothing interesting comes from my playing with different functions.