Determining the camera.fov from a projection matrix from a XR headset

I am well aware that setting fov on a XR camera is ignored, but when working on parts of scenes on a desktop, like people, I was using a 120mm lens to be more like videos / photo shoots. It seemed like a good idea at the time.

camera.fov = 0.265103; // 120mm focal length, source Blender

Now that I am now assembling a scene on a Quest 2, the characters look pretty amazing in PBR, especially with random expression idling, eye movement, & involuntary blinking. She / it looks.narrow though, especially in the head, and everything looks just a little small. I am generating everything in meters, so I think stuff is scaled right.

Think it comes down to that I am not used to looking at stuff with that fov. The default for fov, .80, is better, but still not the same as the headset. I wonder has anyone taken a projection matrix supplied from a Quest and somehow worked out what this camera property would be, if manually set? Think I would switch to that in dev, so that things would look more like they will when in XR.

Also, there are 3 width settings for the headset lenses. Think they are more than mechanical, and change the projection matrices supplied?

Well, I tracked down how fov is used in the computation of the projection matrix, here in math.vector.ts:

     * Stores a left-handed perspective projection into a given matrix with depth reversed
     * @param fov defines the horizontal field of view
     * @param aspect defines the aspect ratio
     * @param znear defines the near clip plane
     * @param zfar not used as infinity is used as far clip
     * @param result defines the target matrix
     * @param isVerticalFovFixed defines it the fov is vertically fixed (default) or horizontally
    public static PerspectiveFovReverseLHToRef(fov: number, aspect: number, znear: number, zfar: number, result: Matrix, isVerticalFovFixed = true): void {
        let t = 1.0 / (Math.tan(fov * 0.5));
        let a = isVerticalFovFixed ? (t / aspect) : t;
        let b = isVerticalFovFixed ? t : (t * aspect);
            a, 0.0, 0.0, 0.0,
            0.0, b, 0.0, 0.0,
            0.0, 0.0, -znear, 1.0,
            0.0, 0.0, 1.0, 0.0,

Seems to me the cleanest way to get the fov from a projection matrix is to look at _m[5] if fov is vertically fixed, and _m[0] if horizontal. Not sure for Quest, guess I’ll just get both.

Shown is for left handed. I do not know which hand is provided, but looking at the right handed way computation, it does not change in this respect.

Reading the private member _m would be a problem in typescript, but only need to do this once per headset, so pg seems that throws up an alert is like the perfect vehicle.

Works. Alerts do not display in XR mode, so you have to hit the “Oculus” button to exit, first, then the alert is displayed. Not going to publish what I actually got to be on the safe side of that NDA to get a developer account.

1 Like