I am currently implementing the Mandelbrot fractal on the GPU. I wrote two programs: the first in OpenGL (desktop C++ application) and the second in WebGL (static webpage). The two programs use almost the same fragment shader for generating the fractal, but picture on WebGL looks less detailed than the OpenGL one. I cannot understand the reason behind that.
OpenGL version:
I place here the fragment shader code:
precision highp float;
float xShift = 200.0;
float yShift = 50.0;
float fade = 0.02;
struct ComplexNumber
{
float Real;
float Imagine;
};
ComplexNumber Product(in ComplexNumber first, in ComplexNumber second)
{
ComplexNumber result;
result.Real = first.Real * second.Real - first.Imagine * second.Imagine;
result.Imagine = first.Real * second.Imagine + first.Imagine * second.Real;
return result;
}
ComplexNumber Add(in ComplexNumber first, in ComplexNumber second)
{
ComplexNumber result;
result.Real = first.Real + second.Real;
result.Imagine = first.Imagine + second.Imagine;
return result;
}
float length2(in ComplexNumber number)
{
return number.Real * number.Real + number.Imagine * number.Imagine;
}
vec4 linearExtrapolation(const vec4 first, const vec4 last, int min, int max, int x)
{
float xDiff = float(max - min);
return first + float(x - min) * (last - first) / xDiff;
}
int getOutOfBoundsIdx()
{
const int nMax = 1000;
ComplexNumber z;
z.Real = 0.;
z.Imagine = 0.;
ComplexNumber c;
c.Real = float((gl_FragCoord.x - xShift ) * fade);
c.Imagine = float((gl_FragCoord.y - yShift) * fade);
for (int i = 0; i < nMax; i++)
{
z = Add (Product(z,z), c);
if (length2(z) > 4.)
{
return i;
}
}
return nMax;
}
void main()
{
const vec4 blue = vec4(166, 202, 240, 255) / 255.;
const vec4 biruz = vec4(123, 228, 209, 255) / 255.;
const vec4 red = vec4(255, 0, 0, 255) / 255.;
const vec4 green = vec4(0, 255, 0, 255) / 255.;
const vec4 black = vec4(0, 0, 0, 255) / 255.;
const int kThreshold0 = 0;
const int kThreshold1 = 100;
const int kThreshold2 = 150;
const int kThreshold3 = 250;
const int kThreshold4 = 390;
int k = getOutOfBoundsIdx();
vec4 color;
if (k < kThreshold1)
{
color = linearExtrapolation(biruz, blue, kThreshold0, kThreshold1, k);
}
else if (k < kThreshold2)
{
color = linearExtrapolation(red, green, kThreshold1, kThreshold2, k);
}
else if (k < kThreshold3)
{
color = linearExtrapolation(biruz, blue, kThreshold2, kThreshold3, k);
}
else if (k < kThreshold4)
{
color = linearExtrapolation(biruz, green, kThreshold3, kThreshold4, k);
}
else
{
color = black;
}
gl_FragColor = color;
}
What can be a reason of such weird difference? I have a feeling that the float operations on WebGL are less precise than in OpenGL.