Betrachten Sie den folgenden Fragment-Shader. Wenn ich es auf dem Simulator oder iPhone 5 (8.3) starte, zeigt es die erwartete Farbe (rot) an. Wenn ich es auf einem iPhone 6 Plus (8.2) starte geht es zur zweiten if-Klausel (grün), die eindeutig falsch ist, da das korrekte Ergebnis der Berechnung bei 1.22 liegen sollte. Wenn ich die Atan-Parameter direkt als Kompilierzeitkonstanten zur Verfügung stelle, funktioniert die Berechnung.GLSL atan auf iPhone 6 Plus gibt ein falsches Ergebnis
Ich habe sowohl auf dem neuesten Xcode 6.2 als auch dem neuesten 6.3 Beta ausprobiert.
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;
}
UPDATE: Plot verdickt.
Wenn ich den Shader in der folgenden Weise ändern, verschwindet der Fehler und atan gibt den richtigen Wert zurück. Es scheint, dass alles, was ich in x und y eingegeben habe, etwas anderes sein muss als Kompilierzeitkonstanten. Das behebt das Problem auch in meinem Produktionscode, wo ich überhaupt keine Kompilierzeitkonstanten habe. BTW das gleiche Problem betrifft auch Acos und 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;
}
Ein anderes Beispiel. So benutze ich das eigentlich.
Wenn ich die Berechnung wie dies zu tun, scheitert es auf 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);
Wenn ich es so machen, es funktioniert:
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);
Aus Interesse ergibt Pi/2 - tan (x, y) Ihnen das Ergebnis, das Sie erwarten (wann immer x
Nein, es gibt genau das gleiche (falsche) Ergebnis. – Seppo