openvr icon indicating copy to clipboard operation
openvr copied to clipboard

Our users say VR world scale is smaller than Real World

Open chihirobelmo opened this issue 2 years ago • 3 comments

We are developing an F-16 flight simulation game. Our community has several users who have real-scale F-16 cockpits. They claim our cockpit looks smaller than in real life. Not only a few people's feelings but several folks claim it is about x0.8 size scaled.

Here is how we implemented the VR FOV and crop.

    float l_left = 0.0f, l_right = 0.0f, l_top = 0.0f, l_bottom = 0.0f;
    float r_left = 0.0f, r_right = 0.0f, r_top = 0.0f, r_bottom = 0.0f;

    vr_pHMD_->GetProjectionRaw(vr::EVREye::Eye_Left,  &l_left, &l_right, &l_top, &l_bottom);
    vr_pHMD_->GetProjectionRaw(vr::EVREye::Eye_Right, &r_left, &r_right, &r_top, &r_bottom);

    D3DXVECTOR2 tanHalfFov =
        D3DXVECTOR2(std::max(std::max(-l_left, l_right),std::max(-r_left, r_right)),
                    std::max(std::max(-l_top, l_bottom),std::max(-r_top, r_bottom)));

    // FOV calc
    aspect_ = tanHalfFov.x / tanHalfFov.y;
    fov_ = 2.0f * atan(tanHalfFov.x) * (180.f / PI);

    // example from Assets\SteamVR\Scripts\SteamVR.cs
    coordLeft_.fLeftU    = 0.5f + 0.5f * l_left   / tanHalfFov.x;  // uMin
    coordLeft_.fRightU   = 0.5f + 0.5f * l_right  / tanHalfFov.x;  // uMax
    coordLeft_.fBottomV  = 0.5f - 0.5f * l_bottom / tanHalfFov.y;  // vMin
    coordLeft_.fTopV     = 0.5f - 0.5f * l_top    / tanHalfFov.y;  // vMax
    
    coordRight_.fLeftU   = 0.5f + 0.5f * r_left   / tanHalfFov.x;  // uMin
    coordRight_.fRightU  = 0.5f + 0.5f * r_right  / tanHalfFov.x;  // uMax
    coordRight_.fBottomV = 0.5f - 0.5f * r_bottom / tanHalfFov.y;  // vMin
    coordRight_.fTopV    = 0.5f - 0.5f * r_top    / tanHalfFov.y;  // vMax

We draw a view with fov_ value horizontal FOV, then we copy and crop textures before submit

   // these are cropping texture which has rendered view in fov_ value.
   // CoordRect { Left, Bottom, Width, Height }
   CoordRect leftSrcRect { coordLeft_.fLeftU,  coordLeft_.fBottomV,  coordLeft_.fRightU  - coordLeft_.fLeftU,  coordLeft_.fTopV  - coordLeft_.fBottomV  };
   CoordRect rightSrcRect{ coordRight_.fLeftU, coordRight_.fBottomV, coordRight_.fRightU - coordRight_.fLeftU, coordRight_.fTopV - coordRight_.fBottomV };
   // cropped textures will be submitted for both eyes.

Can anyone advise us on what can be causing a small-sized world?

chihirobelmo avatar Jan 03 '23 10:01 chihirobelmo

VR headsets often have asymmetric FOV, which results in the optical center in the projection not being aligned with the center of the image. Instead of cropping the textures, you'll likely need to construct an off-center perspective projection matrix to get the correct projection.

Rectus avatar Jan 07 '23 16:01 Rectus

we are using GetProjectionRaw but should we use GetProjectionMatrix instead?

chihirobelmo avatar Jan 12 '23 00:01 chihirobelmo

You can use GetProjectionMatrix if you don't use infinite far-plane projection. It's still possible to use GetProjectionRaw, but you need to create an off-center matrix. Most graphics libraries should have a function for this, like XMMatrixPerspectiveOffCenterRH.

Rectus avatar Jan 13 '23 13:01 Rectus