Atan2 precision in shader


I recently needed to use atan2 to convert position data into lon/lat coordinates in a fragment shader.
The outcome was kind of disturbing as it gives totally wrong values.

inline float2 posToRadial (float3 coords) {
  coords = normalize(coords);

  //calculate latitude:
  float lat = acos(coords.y); //distance from zenit to äquator
    //remaps [0;1] to [PI/2;0]

  lat /= PI; //remap to [1/2;0]
  lat*=2; //remap to [1;0]

  //calculate longitude:
  float lon = atan2(coords.z, coords.x)/PI; //lon around xz plane from -1 to 1
  lon = lon/2+0.5; //remap lon from [-1; 1] to [0; 1] interval

  return float2(lon, lat);

So I mapped this back to read textures with it and when i put in (-1, 0) which is the same as -PI/2 radians it gives me value 0xBC (processed as color and evaluated with color picker) instead of what should be 1/4.

I have rewritten the function for wolframalpha and there the values are correct.

And secondly I have written an atan2 debug shader:

fixed4 frag (v2f i) : SV_Target {
	return (atan2(i.uv.y*2-1, i.uv.x*2-1)/UNITY_PI)/2+0.5;

This shows me that the borders are correct, but everything else is distributed like hell.

Thats it for now.
Hope someone can help, Ty!

I don’t really see any problem with your debug shader. Here’s the result:

The result of the sphere might confuse a bit, but it’s just due to the way it’s unwrapped. Here’s the default sphere’s first UV channel:

The shader simply converts the x-y- UV plane into an angle around the center. This is what you see on the cube. However the texture on the sphere is wrapped around the sphere and the UV seem at the back side is where the left and right side meet.

How exactly do you use your “posToRadial” function in your actual shader? Keep in mind that it only makes sense when used with local space coordinates when the center is (0, 0, 0). Using worldspace coordinates (or even worse clipspace coordinates) would result in complete nonsense.

If you need further help you have to be more precise. Post your complete shader code and an image of what the mesh looks like.