Search code examples
mathhlsl

Return values for arccosine?


I implemented a day/night shader built on the basis that only pixels on the side of an object that is facing the directional light source are illuminated. I calculate this based on the unit vectors between the directional light's position and the position of the pixel in 3D space:

float3 direction = normalize(Light.Position - Object.Position);
float theta = abs(acos(dot(normalize(Object.Position), direction))) * 180 / 3.14f;
if (theta < 180)
    color = float3(1.0f);
else
    color = float3(0.2f);

return float4(color, 1.0f);

This works well, but since I am brushing up on my math lately, it got me thinking that I should make sure I understand what acos is returning.


Mathematically, I know that the arccosine should give me an angle in radians from a value between -1 and 1, while cosine should give me a value between -1 and 1 from an angle in radians.

The documentation states that the input value should be between -1 and 1 for acos which follows that idea, but it doesn't tell me if the return value is 0 - π, -π - π, 0 - 2π, or a similar range.

Return Value

The arccosine of the x parameter.

Type Description

Name [Template Type] 'Component Type' Size
x [scalar, vector, or matrix] 'float' any
ret [same as input x] 'float' same dimension(s) as input x

HLSL doesn't really give me a way to test this very easily, so I'm wondering if anyone has any documentation on this.


What is the return range for the HLSL function acos?


Solution

  • I went through some testing on this topic and have discovered that the HLSL version of acos returns a value between 0 and π. I proved this to be true with the following:

    n = 0..3
    d = [0, 90, 180, 181]
    r = π / 180 * d[n]
    c = cos(r)
    a = acos(c)
    

    The following is the result of the evaluations for d[n]:

    • d[0] returns a = 0.
    • d[1] returns a = π/2.
    • d[2] returns a = π.
    • d[3] returns a ~= 3.12....

    This tells us that the return value for acos stays true to the range of usual principle values for arccosine:

    0 ≤ acos(x) ≤ π

    Also remaining consistent with the definition:

    acos(cos(θ)) = θ


    I have provided feedback to Microsoft with regards to the lack of detailed documentation on HLSL intrinsic functions in comparison to more common languages.