예제 #1
0
        public static void ComposeProjectionMatricesFromFovTanAngles(Fov leftFovTanAngles, float near, float far, out Matrix4x4 left, out Matrix4x4 right)
        {
            Fov nearProjection = leftFovTanAngles * near;

            left  = Matrix4x4Ext.CreateFrustum(-nearProjection.Left, nearProjection.Right, -nearProjection.Bottom, nearProjection.Top, near, far);
            right = Matrix4x4Ext.CreateFrustum(-nearProjection.Right, nearProjection.Left, -nearProjection.Bottom, nearProjection.Top, near, far);
        }
예제 #2
0
        private float GetMaxDiagonalValue(Fov fov)
        {
            float maxHorizontalFov = Mathf.Max(fov.Left, fov.Right);
            float maxVerticalFov   = Mathf.Max(fov.Bottom, fov.Top);

            return(Mathf.Sqrt(maxHorizontalFov * maxHorizontalFov + maxVerticalFov * maxVerticalFov));
        }
예제 #3
0
 public static Rect GetViewportLeft(Fov fovDistances, Vector2 dpm)
 {
     return(new Rect(
                0,
                0,
                (fovDistances.Left + fovDistances.Right) * dpm.x,
                (fovDistances.Bottom + fovDistances.Top) * dpm.y));
 }
예제 #4
0
 public void LoadDefaults()
 {
     ScreenToLensDist  = DefaultValues.ScreenToLensDist;
     DistortionK1      = DefaultValues.DistortionK1;
     DistortionK2      = DefaultValues.DistortionK2;
     InterlensDistance = DefaultValues.InterlensDistance;
     EyeOffsetY        = DefaultValues.EyeOffsetY;
     MaxFovAngles      = DefaultValues.MaxFovAngles;
 }
예제 #5
0
        public void SetFov(Fov fovTanAngles)
        {
            float dist = transform.localPosition.z;

            Fov fovDistances = fovTanAngles * dist;

            transform.localPosition = new Vector3(0.5f * (fovDistances.Right - fovDistances.Left), 0.5f * (fovDistances.Top - fovDistances.Bottom), dist);
            transform.localScale    = new Vector3(fovDistances.Right + fovDistances.Left, fovDistances.Top + fovDistances.Bottom, 1f);
        }
예제 #6
0
 public static Fov Max(Fov fovA, Fov fovB)
 {
     return(new Fov
     {
         Left = Mathf.Max(fovA.Left, fovB.Left),
         Right = Mathf.Max(fovA.Right, fovB.Right),
         Bottom = Mathf.Max(fovA.Bottom, fovB.Bottom),
         Top = Mathf.Max(fovA.Top, fovB.Top),
     });
 }
예제 #7
0
 public static Fov DistortTanAngles(Fov tanAngles, Distortion distortion)
 {
     return(new Fov
            (
                distortion.Distort(tanAngles.Left),
                distortion.Distort(tanAngles.Right),
                distortion.Distort(tanAngles.Bottom),
                distortion.Distort(tanAngles.Top)
            ));
 }
예제 #8
0
 public void LoadFromPrefs()
 {
     ScreenToLensDist  = PlayerPrefsExt.SafeGetFloat(ScreenToLensDistFieldName, DefaultValues.ScreenToLensDist);
     DistortionK1      = PlayerPrefsExt.SafeGetFloat(DistortionK1FieldName, DefaultValues.DistortionK1);
     DistortionK2      = PlayerPrefsExt.SafeGetFloat(DistortionK2FieldName, DefaultValues.DistortionK2);
     InterlensDistance = PlayerPrefsExt.SafeGetFloat(InterlensDistanceFieldName, DefaultValues.InterlensDistance);
     EyeOffsetY        = PlayerPrefsExt.SafeGetFloat(EyeOffsetYFieldName, DefaultValues.EyeOffsetY);
     MaxFovAngles      = new Fov
     {
         Left   = PlayerPrefsExt.SafeGetFloat(MaxFovAnglesLeftFieldName, DefaultValues.MaxFovAngles.Left),
         Right  = PlayerPrefsExt.SafeGetFloat(MaxFovAnglesRightFieldName, DefaultValues.MaxFovAngles.Right),
         Top    = PlayerPrefsExt.SafeGetFloat(MaxFovAnglesTopFieldName, DefaultValues.MaxFovAngles.Top),
         Bottom = PlayerPrefsExt.SafeGetFloat(MaxFovAnglesBottomFieldName, DefaultValues.MaxFovAngles.Bottom)
     };
 }
예제 #9
0
        void UpdateView(HmdParameters hmd, DisplayParameters display)
        {
            Distortion distortion = new Distortion(hmd.DistortionK1, hmd.DistortionK2);

            float zNear = _camWorldLeft.nearClipPlane;
            float zFar  = _camWorldLeft.farClipPlane;

            Fov displayDistancesLeft = Calculator.GetFovDistancesLeft(display, hmd);

            // То, как должен видеть левый глаз свой кусок экрана. Без линзы. C учётом только размеров дисплея
            Fov fovDisplayTanAngles = displayDistancesLeft / hmd.ScreenToLensDist;

            // FoV шлема
            Fov hmdMaxFovTanAngles = Fov.AnglesToTanAngles(hmd.MaxFovAngles);

            // То, как должен видеть левый глаз свой кусок экрана. Без линзы. C учётом размеров дисплея и FoV шлема
            Fov fovEyeTanAglesLeft = Fov.Min(fovDisplayTanAngles, hmdMaxFovTanAngles);

            // То, как должен видеть левый глаз. Мнимое изображение (после увеличения идеальной линзой без искажений). С широким углом. Именно так надо снять сцену
            Fov fovWorldTanAnglesLeft = Calculator.DistortTanAngles(fovEyeTanAglesLeft, distortion);

            Matrix4x4 projWorldLeft;
            Matrix4x4 projWorldRight;

            Calculator.ComposeProjectionMatricesFromFovTanAngles(fovWorldTanAnglesLeft, zNear, zFar, out projWorldLeft, out projWorldRight);

            Matrix4x4 projEyeLeft;
            Matrix4x4 projEyeRight;

            Calculator.ComposeProjectionMatricesFromFovTanAngles(fovDisplayTanAngles, zNear, zFar, out projEyeLeft, out projEyeRight);

            _camWorldLeft.transform.localPosition  = 0.5f * Vector3.left * hmd.InterlensDistance;
            _camWorldRight.transform.localPosition = 0.5f * Vector3.right * hmd.InterlensDistance;

            _camWorldLeft.projectionMatrix  = projWorldLeft;
            _camWorldRight.projectionMatrix = projWorldRight;

            float maxWorldFovTanAngle = GetMaxDiagonalValue(fovWorldTanAnglesLeft);

            UpdateUndistortionTex(distortion, maxWorldFovTanAngle);

            EyeMaterial.SetFloat("_MaxWorldFovTanAngle", maxWorldFovTanAngle);
            EyeMaterial.SetTexture("_UndistortionTex", _undistortionTex);
            EyeMaterial.SetVector("_ProjectionWorldLeft", ComposeProjectionVector(projWorldLeft));
            EyeMaterial.SetVector("_ProjectionEyeLeft", ComposeProjectionVector(projEyeLeft));
        }
예제 #10
0
 public static Fov AnglesToTanAngles(Fov angles)
 {
     return((angles * Mathf.Deg2Rad).GetTan());
 }
예제 #11
0
 public static Fov TanAnglesToAngles(Fov angles)
 {
     return(angles.GetAtan() * Mathf.Rad2Deg);
 }
예제 #12
0
        public static void ComposeProjectionMatricesFromFovAngles(Fov leftFovAngles, float near, float far, out Matrix4x4 left, out Matrix4x4 right)
        {
            Fov leftFovTanAngles = (leftFovAngles * Mathf.Deg2Rad).GetTan();

            ComposeProjectionMatricesFromFovTanAngles(leftFovTanAngles, near, far, out left, out right);
        }