考虑以下片段着色器。当我在模拟器或iPhone 5(8.3)上运行它时,它显示了期望的颜色(红色)。如果我在iPhone 6 Plus(8.2)上运行它,则会进入第二个if子句(绿色),这显然是错误的,因为计算的正确结果应该约为1.22。如果我直接提供atan参数作为编译时常数,则计算有效。
我已经在最新的Xcode 6.2和最新的6.3 Beta上尝试过。
我已经在最新的Xcode 6.2和最新的6.3 Beta上尝试过。
void main()
{
highp float y = 0.57;
highp float x = 0.21;
highp float a = atan(y, x);
// works if changed to atan(0.57, 0.21);
// does not work if changed to atan(y / x);
if (a > 1.2 && a < 1.25)
{
// Should always come here
// Works on Simulator, iPhone 5
gl_FragColor = vec4(1, 0, 0, 1);
}
else if (a > 1.5 && a < 1.55)
{
// Comes here on iPhone 6 Plus
gl_FragColor = vec4(0, 1, 0, 1);
}
return;
}
更新:情况变得更加复杂。
如果我按以下方式更改着色器,错误就会消失,并且atan返回正确的值。似乎我放到x和y中的任何内容都必须是编译时常量之外的其他东西。这也解决了我的生产代码中的问题,因为我根本没有编译时常量。顺便说一下,acos和asin也存在同样的问题。
highp float y = texCoord.x;
highp float x = texCoord.x;
if (x == x) // Removing this line makes error return
{
x = 0.21;
}
if (y == y) // Removing this line makes error return
{
y = 0.57;
}
另一个例子。这是我实际使用的方法。
如果我按照这种方式进行计算,它在 iPhone 6 上会失败:
float y = sin(lon2 - lon1) * cos(lat2);
float x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(lon2 - lon1);
float bearing = atan(y, x) + 2.0 * pi;
return mod(bearing, 2.0 * pi);
如果我这样做,它就可以工作:
float y = texCoord.y;
float x = texCoord.x;
if (y == y)
{
y = sin(lon2 - lon1) * cos(lat2);
}
if (x == x)
{
x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(lon2 - lon1);
}
float bearing = atan(y, x) + 2.0 * pi;
return mod(bearing, 2.0 * pi);