为什么GLSL的算术函数会在iPad上产生与模拟器上不同的结果?

我正在追逐在iOS设备上运行的OpenGL ES 2.0片段着色器代码中的一些错误。 代码在模拟器中运行良好,但在iPad上它有很大的问题,一些计算产生了截然不同的结果,我在iPad上有0.0和在模拟器上有4013.17 ,所以我不是在谈论小差异可能是一些舍入错误的结果。

我注意到的一件事是,在iPad上,

 float1 = pow(float2, 2.0); 

可以产生与结果非常不同的结果

 float1 = float2 * float2; 

具体来说,当对包含较大负数的变量(如-8 pow(x, 2.0)使用pow(x, 2.0)时,它似乎返回一个满足条件的值if (powResult <= 0.0)

此外,两个操作( pow(x, 2.0)以及x*x )的结果在模拟器中产生的结果与在iPad上产生的结果不同。

用过的浮子是mediump ,但是我得到了与highp相同的东西。

对这些差异有一个简单的解释吗?

我正在缩小问题范围,但需要花费很多时间,所以也许有人可以通过一个简单的解释来帮助我。

GLSL ES文档说如果x <0或x = 0且y≤0,则pow未定义。

模拟器使用x86浮点单元和Mac OS X数值库。 iPad使用ARM FPU。

pow()也是一个使用近似算法的库例程。

在GLSL中, pow作为exp2log2的函数实现。 由于对数函数没有定义为负实数,因此pow()也不是。

请参阅GLSL ES 3.0规范第47页或GLSL 4.4规范第88页。

pow (x,y)从exp2inheritance(x * log2 (y))

同样来自规范:

genType pow (genType x,genType y)

  • 返回x上升到y次幂,即x ^ y
  • 如果x <0,则结果未定义。
  • 如果x = 0且y <= 0,则结​​果未定义。