Robust atan(y,x) on GLSL for converting XY coordinate to angle

后端 未结 5 683
花落未央
花落未央 2021-02-02 16:34

In GLSL (specifically 3.00 that I\'m using), there are two versions of atan(): atan(y_over_x) can only return angles between -PI/2, PI/2, while

5条回答
  •  时光说笑
    2021-02-02 17:15

    Depending on your targeted platform, this might be a solved problem. The OpenGL spec for atan(y, x) specifies that it should work in all quadrants, leaving behavior undefined only when x and y are both 0.

    So one would expect any decent implementation to be stable near all axes, as this is the whole purpose behind 2-argument atan (or atan2).

    The questioner/answerer is correct in that some implementations do take shortcuts. However, the accepted solution makes the assumption that a bad implementation will always be unstable when x is near zero: on some hardware (my Galaxy S4 for example) the value is stable when x is near zero, but unstable when y is near zero.

    To test your GLSL renderer's implementation of atan(y,x), here's a WebGL test pattern. Follow the link below and as long as your OpenGL implementation is decent, you should see something like this:

    GLSL atan(y,x) test pattern

    Test pattern using native atan(y,x): http://glslsandbox.com/e#26563.2

    If all is well, you should see 8 distinct colors (ignoring the center).

    The linked demo samples atan(y,x) for several values of x and y, including 0, very large, and very small values. The central box is atan(0.,0.)--undefined mathematically, and implementations vary. I've seen 0 (red), PI/2 (green), and NaN (black) on hardware I've tested.

    Here's a test page for the accepted solution. Note: the host's WebGL version lacks mix(float,float,bool), so I added an implementation that matches the spec.

    Test pattern using atan2(y,x) from accepted answer: http://glslsandbox.com/e#26666.0

提交回复
热议问题