Reputation: 35
I have double 'radius' = 2.0E-45, when i set it to ~2.0E-46 calculation collapse resulting in white screen. So seems like issue is overflow. I wrote the same algorithm but using nubma cuda and f64 (double precision) 'radius'. And everything works fine. I am using f32 texture buffer for 'depth_array' (there is no float64 dtype for this), but numba implementation works fine with f32, and opengl implementation also works fine until 'radius' bigger than ~2.0E-46. Why numba implementation works, while opengl not? I want to stick with opengl. Is there any possibility to fix it?
I only put in parts that use the 'radius'. All other variables are double type. (code is messy and just a scratch)
#version 150
#extension GL_ARB_gpu_shader_fp64 : enable
double radius = 2.0E-45;
...
dvec2 pixel = dvec2(gl_FragCoord.xy) + dvec2(-0.5+(double(x)+0.5)/double(AA),-0.5+(double(y)+0.5)/double(AA));
dvec2 c = pixel/dvec2(width, height) * dvec2(radius, radius) + dvec2(-radius/2, -radius/2);
color.rgb += sample(c);
...
vec3 sample(dvec2 dn)
{
vec3 color = vec3(0.0,0.0,0.0);
dvec2 d0 = dn;
double zn_size = 0.0;
int i = 0;
while (i < depth)
{
int x = i % depth;
dvec2 value = dvec2(texelFetch(depth_array, x).rg);
dn = complex_mul(dn, value + dn);
dn = dn + d0;
i++;
x = i % depth;
value = dvec2(texelFetch(depth_array, x).rg);
dvec2 zn = value * 0.5 + dn;
zn_size = dot(zn, zn);
if (zn_size > r)
{
double fraciter = (zn_size-r)/(r2-r);
double iter = double(i) - fraciter;
double m = sqrt(iter)*mul*2.0;
color = sin(vec3(.1, .15, .2)*float(m)*0.5)*.5+0.5;
break;
}
}
return color;
}
Upvotes: 2
Views: 448
Reputation: 474036
In GLSL, the literal value 2.0E-45
has the type float
. That means the value will be squashed into the valid range of a float
before it gets assigned to a value.
If you want a literal to be a double
, then it needs to use the proper suffix: 2.0E-45lf
.
Upvotes: 3