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

时间:2012-08-31 21:34:46

标签: ios opengl-es floating-point opengl-es-2.0 glsl

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

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

float1 = pow(float2, 2.0);

可以产生与

结果非常不同的结果
float1 = float2 * float2;

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

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

使用过的浮点数为mediump,但我使用highp得到的内容相同。

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

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

3 个答案:

答案 0 :(得分:16)

GLSL ES documentation表示如果x&lt; 0或者如果x = 0且y≤0。

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

在GLSL中,powexp2log2的函数。由于logarithm function未定义为负实数,pow()也不是。

请参阅第{47页的GLSL ES 3.0 specification或第88页的GLSL 4.4 specification

  

pow (x,y)继承自 exp2 (x * log2 (y))

同样来自规范:

  

genType pow (genType x,genType y)

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