• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
1
Question by unity_hyTLZfC7oY2FZg · Apr 21, 2021 at 10:21 AM · vroculusportalstereoscopicstereo

Right eye projection matrix is incorrect VR stereo portal

Has anyone figured out how to get the correct left and right eye projection matrixes in Unity? My left eye looks exactly correct, however, my right eye projection matrix makes it so that objects warp when moving my HMD. I am using the Oculus Quest 2 with the OVR dev kit.
I am trying to make a portal effect, and when I close my left eye it looks perfect. Here is a video, but it doesn't demonstrate the problem (as it only occurs in the left eye). Video Example
Here is the code that I am using to get the projection matrixes for each eye:

 // left eye projection matrix
 OVRManager.instance.gameObject.GetComponent<OVRCameraRig>().leftEyeCamera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Left)
 // right eye projection matrix
 OVRManager.instance.gameObject.GetComponent<OVRCameraRig>().rightEyeCamera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Right)

Here is what I am doing to render the eyes to textures (it is a modified version of the HTC Stereo Rendering package)

 private void RenderToTwoStereoTextures(VRRenderEventDetector detector)
             {
                 // get eye poses
                 var leftEyeOffset = StereoRenderManager.Instance.paramFactory.GetEyeSeperation(0);
                 var leftEyeRotation = StereoRenderManager.Instance.paramFactory.GetEyeLocalRotation(0);
     
                 var rightEyeOffset = StereoRenderManager.Instance.paramFactory.GetEyeSeperation(1);
                 var rightEyeRotation = StereoRenderManager.Instance.paramFactory.GetEyeLocalRotation(1);
     
                 // render stereo textures
                 RenderEye(
                     leftEyeOffset, leftEyeRotation, 
                     leftProjMatrix, detector.unityCamera.worldToCameraMatrix, 
                     leftEyeTexture, "_LeftEyeTexture");
     
                 var rightEyeWorldToCameraMatrix = detector.unityCamera.worldToCameraMatrix;
                 rightEyeWorldToCameraMatrix.m03 -= 2.0f * Mathf.Abs(leftEyeOffset.x);
     
                 RenderEye(
                     rightEyeOffset, rightEyeRotation,
                     rightProjMatrix, rightEyeWorldToCameraMatrix,
                     rightEyeTexture, "_RightEyeTexture");
             }
 
         private void RenderToTwoStereoTextures(VRRenderEventDetector detector)
         {
             // get eye poses
             var leftEyeOffset = StereoRenderManager.Instance.paramFactory.GetEyeSeperation(0);
             var leftEyeRotation = StereoRenderManager.Instance.paramFactory.GetEyeLocalRotation(0);
 
             var rightEyeOffset = StereoRenderManager.Instance.paramFactory.GetEyeSeperation(1);
             var rightEyeRotation = StereoRenderManager.Instance.paramFactory.GetEyeLocalRotation(1);
 
             // render stereo textures
             RenderEye(
                 leftEyeOffset, leftEyeRotation, 
                 leftProjMatrix, detector.unityCamera.worldToCameraMatrix, 
                 leftEyeTexture, "_LeftEyeTexture");
 
             var rightEyeWorldToCameraMatrix = detector.unityCamera.worldToCameraMatrix;
             rightEyeWorldToCameraMatrix.m03 -= 2.0f * Mathf.Abs(leftEyeOffset.x);
 
             RenderEye(
                 rightEyeOffset, rightEyeRotation,
                 rightProjMatrix, rightEyeWorldToCameraMatrix,
                 rightEyeTexture, "_RightEyeTexture");
         }
 
 
         private Vector4 GetCameraSpacePlane(Camera cam, Vector3 pt, Vector3 normal)
         {
             Matrix4x4 m = cam.worldToCameraMatrix;
             Vector3 camSpacePt = m.MultiplyPoint(pt);
             Vector3 camSpaceNormal = m.MultiplyVector(normal).normalized;
             return new Vector4(
                 camSpaceNormal.x,
                 camSpaceNormal.y,
                 camSpaceNormal.z,
                 -Vector3.Dot(camSpacePt, camSpaceNormal));
         }
 
         private Vector4 GetObliqueNearClipPlane()
         {
             var clipPlaneCameraSpace = Vector4.zero;
             if (!isMirror)
             {
                 clipPlaneCameraSpace = GetCameraSpacePlane(stereoCameraEye, anchorPos, anchorForward);
             }
             else
             {
                 // get reflection plane -- assume +y as normal
                 float d = -Vector3.Dot(canvasOriginUp, canvasOriginPos) - reflectionOffset;
                 Vector4 reflectionPlane = new Vector4(canvasOriginUp.x, canvasOriginUp.y, canvasOriginUp.z, d);
 
                 clipPlaneCameraSpace = GetCameraSpacePlane(stereoCameraEye, canvasOriginPos, reflectionPlane);
             }
 
             return clipPlaneCameraSpace;
         }
 
         private Rect GetScissorRect(Matrix4x4 mat)
         {
             var renderer = GetComponent<Renderer>();
             Vector3 cen = renderer.bounds.center;
             Vector3 ext = renderer.bounds.extents;
             Vector3[] extentPoints = new Vector3[8]
             {
                  WorldPointToViewport(mat, new Vector3(cen.x-ext.x, cen.y-ext.y, cen.z-ext.z)),
                  WorldPointToViewport(mat, new Vector3(cen.x+ext.x, cen.y-ext.y, cen.z-ext.z)),
                  WorldPointToViewport(mat, new Vector3(cen.x-ext.x, cen.y-ext.y, cen.z+ext.z)),
                  WorldPointToViewport(mat, new Vector3(cen.x+ext.x, cen.y-ext.y, cen.z+ext.z)),
                  WorldPointToViewport(mat, new Vector3(cen.x-ext.x, cen.y+ext.y, cen.z-ext.z)),
                  WorldPointToViewport(mat, new Vector3(cen.x+ext.x, cen.y+ext.y, cen.z-ext.z)),
                  WorldPointToViewport(mat, new Vector3(cen.x-ext.x, cen.y+ext.y, cen.z+ext.z)),
                  WorldPointToViewport(mat, new Vector3(cen.x+ext.x, cen.y+ext.y, cen.z+ext.z))
             };
 
             bool invalidFlag = false;
             Vector2 min = extentPoints[0];
             Vector2 max = extentPoints[0];
             foreach (Vector3 v in extentPoints)
             {
                 // if v.z < 0 means t$$anonymous$$s projection is unreliable
                 if (v.z < 0)
                 {
                     invalidFlag = true;
                     break;
                 }
 
                 min = Vector2.Min(min, v);
                 max = Vector2.Max(max, v);
             }
 
             if (invalidFlag)
             {
                 return fullViewport;
             }
             else
             {
                 min = Vector2.Max(min, Vector2.zero);
                 max = Vector2.Min(max, Vector2.one);
                 return new Rect(min.x, min.y, max.x - min.x, max.y - min.y);
             }
         }
 
         private Matrix4x4 GetScissorMatrix(Rect rect)
         {
             Matrix4x4 m2 = Matrix4x4.TRS(
                 new Vector3((1 / rect.width - 1), (1 / rect.height - 1), 0),
                 Quaternion.identity,
                 new Vector3(1 / rect.width, 1 / rect.height, 1));
 
             Matrix4x4 m3 = Matrix4x4.TRS(
                 new Vector3(-rect.x * 2 / rect.width, -rect.y * 2 / rect.height, 0),
                 Quaternion.identity,
                 Vector3.one);
 
             return m3 * m2;
         }
 
         private Vector3 WorldPointToViewport(Matrix4x4 mat, Vector3 point)
         {
             Vector3 result;
             result.x = mat.m00 * point.x + mat.m01 * point.y + mat.m02 * point.z + mat.m03;
             result.y = mat.m10 * point.x + mat.m11 * point.y + mat.m12 * point.z + mat.m13;
             result.z = mat.m20 * point.x + mat.m21 * point.y + mat.m22 * point.z + mat.m23;
 
             float a = mat.m30 * point.x + mat.m31 * point.y + mat.m32 * point.z + mat.m33;
             a = 1.0f / a;
             result.x *= a;
             result.y *= a;
             result.z = a;
 
             point = result;
             point.x = (point.x * 0.5f + 0.5f);
             point.y = (point.y * 0.5f + 0.5f);
 
             return point;
         }
  


Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by unity_hyTLZfC7oY2FZg · Apr 21, 2021 at 02:53 PM

@bgolus Do you have any idea why t$$anonymous$$s might be happening? You seem to know a lot about stereo rendering, so it would be greatly appreciated if you have any idea what's going on. My right eye projection matrix in Unity is incorrect w$$anonymous$$le my left eye projection matrix is correct.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

159 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Stereo 360 video Pause/Play Not Working - Works with Mono Videos? 0 Answers

How Can I Combine Stereo Screen? 0 Answers

Supporting both GearVR and GoogleVR in single .APK ? 1 Answer

Use OVRPlugin or not 1 Answer

Oculus Go OBB Expansion File Crashes App when Loading Second Scene 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges