GLSL の atan 関数は x=0 のとき未定義

試した環境

  • glsl4.30

本題

前回の記事で、球面座標系のφの変換を y の符号と acos を使って求めました。 それは日本語版 Wikipedia球面座標系のページの記述を参考にしました。 ところで英語版 WikipediaSpherical coordinate system のページではφへの変換式が atan2 関数を用いる式で示されています。 式とその説明文を引用します。

φ = arctan y/x
The inverse tangent denoted in φ = arctan y/x must be suitably defined, taking into account the correct quadrant of (x, y). See the article on atan2.

この変換を GLSL で実装しようとした場合、GLSL には atan2 関数がありません。 GLSL には atan 関数があり、atan2 関数のように2つの引数を入力する書き方もできます。 しかし x=0 のとき、出力は未定義です。 リファレンスの記述を引用します。

the signs of y and x are used to determine the quadrant that the angle lies in. The value returned by atan in this case is in the range [−π,π]. The result is undefined if x=0.

atan2 関数のように値域が[−π,π]ですが、x=0のときに −π/2 か π/2 かはこの関数では得られません。 x=0ならばyの符号を調べるといった以下のような処理を追加しなければならないでしょう。

const float HALF_PI = 1.57079632679489661923132169163975144;
float atan2(float y, float x){
    if (x == 0.0) {
        return y < 0.0 ? -HALF_PI : HALF_PI;
    }
    return atan(y, x);
}

float の等価演算や x=0, y=0 の時の挙動などを考慮すると、上記の処理では不十分でしょう。

参考

atan - OpenGL 4 Reference Pages

Spherical coordinate system - Wikipedia