VR Portal in build has incorrect projection (sometimes)

Hi,

I’m having a problem with my VR portal when playing in build but only some of the time!

I have a camera that renders a texture and applies this to a quad to produce the portal (when moving). This generally works but every so often it doesn’t produce the correct projection and I get a weird squashed effect.

This is the exact same code running in build:

Projection incorrect:

Projection correct:

I kinda modified the OpenVR portals found in this thread: Rendering portals in Unity 5.4 with native OpenVR? :: SteamVR Developer Hardware General Discussions to work with native/OVR.

Here is the code:

    public void RenderIntoMaterial(Material mat)
    {
        if (Camera.current != mainCamera)
            return;

        // Set local rotation
        portalCameraTransform.localRotation = mainCameraTransform.localRotation;
        Vector3 localPos = mainCameraTransform.localPosition;

        // Left eye
        Vector3 eyeOffset = InputTracking.GetLocalPosition(VRNode.LeftEye);
        portalCameraTransform.localPosition = eyeOffset;

        if (DD_DeviceManager.Instance.vrType == DD_DeviceManager.VRType.Oculus)
            portalCamera.SetStereoProjectionMatrix(Camera.StereoscopicEye.Left, portalCamera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Left));
        else
            portalCamera.projectionMatrix = HMDMatrix4x4ToMatrix4x4(SteamVR.instance.hmd.GetProjectionMatrix(Valve.VR.EVREye.Eye_Left, mainCamera.nearClipPlane, mainCamera.farClipPlane, Valve.VR.EGraphicsAPIConvention.API_DirectX));
       
        // Set Render texture
        portalCamera.targetTexture = leftEyeRenderTexture;
        portalCamera.Render();
       
        // Right eye
        eyeOffset = InputTracking.GetLocalPosition(VRNode.RightEye);
        portalCameraTransform.localPosition = eyeOffset;

        // Set projection
        if (DD_DeviceManager.Instance.vrType == DD_DeviceManager.VRType.Oculus)
            portalCamera.SetStereoProjectionMatrix(Camera.StereoscopicEye.Right, portalCamera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Right));
        else
            portalCamera.projectionMatrix = HMDMatrix4x4ToMatrix4x4(SteamVR.instance.hmd.GetProjectionMatrix(Valve.VR.EVREye.Eye_Right, mainCamera.nearClipPlane, mainCamera.farClipPlane, Valve.VR.EGraphicsAPIConvention.API_DirectX));

        // Set Render Texture
        portalCamera.targetTexture = rightEyeRenderTexture;
        portalCamera.Render();

        // Reset
        portalCameraTransform.localPosition = localPos;

        mat.SetTexture("_LeftEyeTexture", leftEyeRenderTexture);
        mat.SetTexture("_RightEyeTexture", rightEyeRenderTexture);
    }

This works 100% in the editor and I would say 75% of the time in the build. I can’t put down what it could be in the build. I imagine something about how GetStereoProjection and SetStereoProjection is working? Or perhaps how the PortalCamera is initialising?

Some help on this would really be appreciated. Also, if there are any ideas on how to achieve a similar effect without using additional camera and portal would be great. I’m thinking perhaps similar effect could be achieved with post-process + stencil buffer but haven’t much experience there.

Many thanks!

Just noticed that when creating the texture I used VRSettings.eyeTextureWidth but it doesn’t look like this always provides the correct numbers. So I think that’s it.

Do tell. Can you elaborate on what you did to remedy the issue? Did you get the eye resolution from the OVRPlugin? I’m also curious as to why your sample code appears to set the stereo projection matrix to itself.
portalCamera.SetStereoProjectionMatrix(Camera.StereoscopicEye.Left, portalCamera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Left));

Hi,

I just manually set the eye resolution based on the device type. If you found a better way to generate automatically that would be great to know!?

The example code is wrong, that was a mistake left over from some previous testing using another camera. It can be safely removed.

Thanks!