Skip to main content
Inspiring
June 12, 2014

Zooming with the new SDK

I can imagine that the ability to zoom in a VR game is a sensitive topic, and likely to invite a "don't do that" / "violation of best practices", etc. As far as I can tell, users enjoy the zoom feature in Titans of Space, and Yosemite Spyglass made great use of it. Then you have something like Private Eye where the whole premise is looking through binoculars. I believe Desperate Gods also has an implementation of zoom as well, but I imagine positional tracking would render it obsolete in that particular case.

In the past, I accomplished this by smoothly adjusting the OVRCameraController's vertical FOV via SetVerticalFOV(), and this worked reasonably well as long as you're not zooming onto something that's very close to you.

In the newer SDK however, SetVerticalFOV() appears to have new behavior, where it simply changes the size of the "hole" through which the player can view the scene. Understandable, because the true rendered FOV is now internally calculated as a function of eye relief and other factors.

In addition, probably because it has to recalculate the distortion mesh every time something fundamental as the FOV is changed, this sort of smooth adjustment incurs a serious performance hit. In the video below, it goes from 125 FPS (capped at 60 in the video because of video capture software) down to 45-50 FPS when SetVerticalFOV() is being called every frame with a new value.




I suppose there are other options for zooming, such as moving the actual camera rig itself out along the line of sight but this breaks down if there's anything in the foreground that should be in the zoomed view, and in general it's really not the same since it also involves a change in perspective.

Any suggestions from other devs that have played with zooming and the new SDK, or even suggestions from the Oculus team on what the recommended approach should be going forward? Many thanks in advance!
    This topic has been closed for replies.

    33 replies

    drashAuthor
    Inspiring
    August 6, 2014
    Thanks for posting your helpful code renaudbedard!

    I would like to point out that the "default" horizontal FOV halfangles that the Unity Integration normally uses aren't necessarily symmetric, so be careful with this approach. It may change from user to user, but my leftTan and rightTan values were different for each eye. I've been proportionally scaling my default tan values, because if I don't do that, the world feels vertically squished a little bit (even when using aspect ratio correctly).
    Titans of Space PLUS for Quest is now available on DrashVR.com
    New Participant
    August 6, 2014
    @unclebob : You don't actually have to set the fieldOfView directly on the two Cameras under the Controller, you can use the VerticalFOV property (or SetVerticalFOV) on the Controller and it'll propagate the values to both.

    @drash : Good to know! I'll see what my default values look like and scale accordingly.
    Up and Coming
    August 17, 2014
    Zoom using FieldOfView on each camera seems to be working fine.

    Cheers

    Unclebob
    Feel free to drop by.... http://www.VRCraftworks.com and contact us
    Inspiring
    August 27, 2014
    I tried using the alternate function written by renaudbedard with SDK version 0.4.1, but it messes up the FOV even when I'm not manipulating anything. The view is vertically squashed a little bit. Did something change?

    I hope Oculus gives us an official way to adjust the FOV during gameplay soon.
    Inspiring
    August 27, 2014
    You can still set OVRCameraController.VerticalFOV from script in your Update() function. But I would suggest rendering to a separate "telescope" viewer or similar instead. You will break presence by messing with the projection of the user's eyeballs.
    Inspiring
    August 27, 2014
    "vrdaveb" wrote:
    You can still set OVRCameraController.VerticalFOV from script in your Update() function. But I would suggest rendering to a separate "telescope" viewer or similar instead. You will break presence by messing with the projection of the user's eyeballs.


    That doesn't work for me (with renaudbedard's changes disabled). Should it? If I need to enable renaudbedard's changes, then I have the squashed FOV issue I mentioned...
    Inspiring
    August 27, 2014
    It should work from the Update function. It won't work in Awake or Start.
    Inspiring
    August 27, 2014
    "vrdaveb" wrote:
    It should work from the Update function. It won't work in Awake or Start.


    I have this in a script attached to the OVR Camera Controller:

    function Update () {
    if (Input.GetButtonDown("Fire2") == true)
    {
    Debug.Log("Zooming in now");
    camController.VerticalFOV = zoomFOV;
    }
    else if (Input.GetButtonUp("Fire2") == true)
    {
    camController.VerticalFOV = origFOV;
    }
    }


    I can see the bounding box change on OVRCameraController in the Scene view of the Editor, so I know it's having an effect. It doesn't change the actual view in the game window, and it doesn't change the view in the compiled DirectToRift.
    drashAuthor
    Inspiring
    August 27, 2014
    "weasel47" wrote:
    I can see the bounding box change on OVRCameraController in the Scene view of the Editor, so I know it's having an effect. It doesn't change the actual view in the game window, and it doesn't change the view in the compiled DirectToRift.

    Are you sure you're using the latest Unity integration (0.4.1)? I'm able to change the FOV on the fly by setting the OVRCameraController.VerticalFOV or .SetVerticalFOV(), and it actually changes the FOV like you would expect.

    While I'm here on this thread, I thought I would point out that to properly determine your "non-zoom" FOV, the below line of code seems to be a good SDK-friendly way to do that, given you have a reference to the OVRCameraController (riftCameraController):

    nonZoomFOV = riftCameraController.CameraMain.GetComponent<OVRCamera>().GetIdealVFOV();
    Titans of Space PLUS for Quest is now available on DrashVR.com
    Inspiring
    August 27, 2014
    "drash" wrote:
    Are you sure you're using the latest Unity integration (0.4.1)? I'm able to change the FOV on the fly by setting the OVRCameraController.VerticalFOV or .SetVerticalFOV(), and it actually changes the FOV like you would expect.

    While I'm here on this thread, I thought I would point out that to properly determine your "non-zoom" FOV, the below line of code seems to be a good SDK-friendly way to do that, given you have a reference to the OVRCameraController (riftCameraController):

    nonZoomFOV = riftCameraController.CameraMain.GetComponent<OVRCamera>().GetIdealVFOV();


    Hey thanks, it turns out I had updated everything else to 0.4.1 but not the Unity Integration! Oops.

    Thanks also for the suggestion for getting the "non-zoom."

    Now that I'm updating the Unity Integration, it leads me to another set of questions. I had added several things to the Camera Controller object... new scripts and new child objects. My existing Camera Controller object / prefab still isn't able to zoom, but when I recreate it with the prefab from the new Integration, it does work. They should both be accessing the updated scripts. Is that to be expected? If so, are there any better ways to do things so that I don't have to redo my own prefab every time there's a new Unity Integration version? I guess I could add child objects through a script rather than in the editor, for example...

    EDIT: Never mind. I dragged my prefab version of the Camera Controller into the scene again and it's working this time.

    EDIT 2: Now I see why I was having problems. For some reason, my script ONLY works if the OVRCameraController is currently selected in the object Hierarchy in the editor. If I select something else (even a child object), the script stops working until I select OVRCameraController again (the logging does still show that my input is recognized each time). My script does not work in the compiled build.

    EDIT 3: I switched to using the functions to set FOV rather than changing the values directly. That seems to have done the trick. I'm still having trouble getting the IdealFOV as suggested (I'm using JavaScript, which complicates things).

    EDIT 4: I see, I just had to replace "riftCameraController" with the variable name I was using for the OVRCameraController script. Hooray! Now I can start accomplishing things again.