Full implementation of Camera.WorldToViewportPoint for Burst

I’ve seen a few implementations of Camera.WorldToViewportPoint on the forum that were incomplete so this is (as far as I can tell) a complete recreation that correctly returns the value in viewport space with the distance to the camera in Z.

    /// <summary>
    /// Recreation of Camera.WorldToViewportPoint including distance to camera in Z for use in Burst.
    /// </summary>
    [MethodImpl(MethodImplOptions.AggressiveInlining)]
    public static float3 WorldToViewportPoint(in float4x4 cameraView, in float4x4 cameraProjection, float3 point)
    {
        var viewPos = math.mul(cameraView, new float4(point, 1.0f));
        var clip = math.mul(cameraProjection, viewPos);
        // -0.5 to 0.5
        var ndc = clip.xy / clip.w;
        // 0 to 1
        var viewport = (ndc + 1.0f) / 2.0f;
        return new float3(viewport.x, viewport.y, -viewPos.z);
    }

( Special thanks to @eizenhorn on discord and @bgolus reply on Camera.WorldToViewportPoint math )

3 Likes

Hi, the z vaule is not correct in your implementation. And it should be:

 [BurstCompile(FloatPrecision.Medium, FloatMode.Fast)]
public static void WorldToViewport(in float4x4 viewMat, in float4x4 projMat,
                                   in float3 worldPoint, ref float3 viewportPoint)
{
    var viewPos = math.mul(viewMat, new float4(worldPoint, 1));
    var clipPos = math.mul(projMat, viewPos);
    var ndc = clipPos.xy / clipPos.w;
    viewportPoint = new float3(ndc.x * 0.5f + 0.5f, ndc.y * 0.5f + 0.5f, -viewPos.z);
}

Your implementation is the same?

Sorry! i misread your code. you are using the -viewPos.z, i misread it to -viewport.z.Your implementation is correct.

1 Like