opengl - OpenGL双溢出
问题描述
我有双“半径”= 2.0E-45,当我将它设置为 ~2.0E-46 计算崩溃导致白屏。所以似乎问题溢出了。我编写了相同的算法,但使用了 nubma cuda 和 f64(双精度)“半径”。一切正常。我将 f32 纹理缓冲区用于“depth_array”(没有 float64 dtype),但 numba 实现与 f32 一起工作正常,opengl 实现也可以正常工作,直到“半径”大于 ~2.0E-46。为什么 numba 实现有效,而 opengl 无效?我想坚持使用opengl。有没有可能修复它?
我只放入使用“半径”的部分。所有其他变量都是双精度类型。(代码很乱,只是一个划痕)
#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;
}
解决方案
在 GLSL 中,文字值 2.0E-45
的类型为float
。这意味着在将值分配给值float
之前,该值将被压缩到 a 的有效范围内。
如果您希望文字是 a double
,那么它需要使用正确的后缀:2.0E-45lf
。
推荐阅读
- bash - 如何使用 PowerShell 提取嵌套密码保护的 zip 文件夹指定次数?
- powershell - 切换“使用 Powershell 显示隐藏的文件和文件夹
- java - 截取 URL 证书 Chrome - Selenium
- google-apps-script - Google 脚本编辑器(Google Apps 脚本)中未定义“OAuth2”对象
- kotlin - 流动变换中是否有“线性”的定义?
- sql - 从 SELECT 语句填充的插入语句中添加 OUTPUT inserted.columnname
- javascript - 如何将 JSON 提取数据分离到不同的 div 中
- r - 按范围分组数据,而不是 R 中的所有数字数据
- angular - 如何使用带有外部 IdentityServer 的 OAuth2 保护 Angular 代码
- python - 将值和函数重新序列化到 Python 中的新环境中