Why does GLSL's arithmetic functions yield so

2019-03-28 00:04发布

I'm currently chasing some bugs in my OpenGL ES 2.0 fragment shader code which is running on iOS devices. The code runs fine in the simulator, but on the iPad it has huge problems and some of the calculations yield vastly different results, I had for example 0.0 on the iPad and 4013.17 on the simulator, so I'm not talking about small differences which could be the result of some rounding errors.

One of the things I noticed is that, on the iPad,

float1 = pow(float2, 2.0);

can yield results which are very different from the results of

float1 = float2 * float2;

Specifically, when using pow(x, 2.0) on a variable containing a larger negative number like -8, it seemed to return a value which satified the condition if (powResult <= 0.0).

Also, the result of both operations (pow(x, 2.0) as well as x*x) yields different results in the simulator than on the iPad.

Used floats are mediump, but I get the same stuff with highp.

Is there a simple explanation for those differences?

I'm narrowing the problem down, but it takes so much time, so maybe someone can help me here with a simple explanation.

3条回答
smile是对你的礼貌
2楼-- · 2019-03-28 00:31

The simulator uses an x86 floating point unit and Mac OS X numerical libraries. The iPad uses either an ARM FPU.

Also pow() is a library routine that uses an approximation algorithm.

查看更多
姐就是有狂的资本
3楼-- · 2019-03-28 00:33

The GLSL ES documentation says pow is undefined if x < 0 or if x = 0 and y ≤ 0.

查看更多
闹够了就滚
4楼-- · 2019-03-28 00:41

In GLSL pow is implemented as a function of exp2 and log2. Since the logarithm function is not defined for negative real numbers, pow() is not either.

See the GLSL ES 3.0 specification page 47, or GLSL 4.4 specification page 88.

pow(x, y) Inherited from exp2(x * log2(y))

Also from the specification:

genType pow(genType x, genType y)

  • Returns x raised to the y power, i.e., x^y
  • Results are undefined if x < 0.
  • Results are undefined if x = 0 and y <= 0.
查看更多
登录 后发表回答