WebGL:exp()异常不准确

时间:2018-08-05 03:33:53

标签: glsl webgl webgl2

我只是对1到50之间的数字进行了循环,并打印了WebGL的exp(float)计算。我使用的是highp精度,这些是来自WebGL2。

   precision highp float;
    varying vec2 TexCoords;
    uniform highp sampler2D A;

    void main() {
      float result = exp(texture2D(A, TexCoords).r);
      gl_FragColor.r = result;
    }

我在javascript中运行了相同的内容,并比较了结果。事物非常聪明,但很快就会累加起来。

所以我还比较了javascript和python(numpy)的结果,它们非常可比。

以下是Math.abs(diff)中的最后几个数字:

  

Diffs','8.25484005595456e-8,   3.700182968913168e-7,   0.0000037810978241736848,   0.0000055018942362039525,   0.000003128868712565236,... 12720537652,21883728284,30738633104,20683268800,324543434496,2989835245824,6539001840640,   12329169293312、110431739568128、262788127178752、615023709454336,   1369528883085312,3028196912005120

这些是javascript和pyton之间的最后几个区别 :

  

3.0517578125e-05   6.103515625e-05   0.0   0.0 ...   0.0   0.0   0.0   0.0   0.0   32.0   0.0   0.0 ...   0.0   0.0   0.0   262144.0

这些是WebGL程序的前几个数字:

  

“ WebGL的结果”,   '2.7182817459106445,7.3890557289123535,20.085533142089844,

和来自javascript:

  

“来自javascript的结果”,   '2.718281828459045,7.38905609893065,20.085536923187668,

1 个答案:

答案 0 :(得分:4)

不是 WebGL 用户,所以我可能是错的,但是您的差异表明, WebGL 的前6-7位数字正确。听起来32bit浮点精度正确(仅尾数为23bits

javascript 结果在与64bit double对应的前16位数字中是正确的,因此您很可能比较32bit64bit计算,因此它的精确度也就不足为奇了。

这里比较:

WebGL     : 2.7182817459106445 ,7.3890557289123535 ,20.085533142089844  ,
javascript: 2.718281828459045  ,7.38905609893065   ,20.085536923187668  ,
PI float  : 2.71828174591064453,7.38905572891235352,20.08553504943847656,
PI double : 2.71828182845904509,7.38905609893064952,20.08553692318766437,
x87 double: 2.7182818284590451 ,7.3890560989306504 ,20.0855369231876679 ,

前两行是您的电话号码。 PI行是通过e32bit x87 的常数64bit的乘积计算得出的。最后一行使用 x87 FPU 内部e^x实现80bit -> 64bit

正如您所见, WebGL 32bit的关联关系非常紧密地支持了我的结论。