private void SetupCameraUpdateCallback(EyeType type)
        {
            var eyeCamera          = _eyeCamera[type];
            var eyeTransform       = _eyeTransform[type];
            var homographyMaterial = _eyeCamMaterial[type];

            Action <Camera> updateState = (camera) =>
            {
                _faceTracker.GetCurrentFacePose(out _currentFacePose);
                var eyePose = _currentFacePose.GetEyePose(type);
                eyeTransform.SetPositionAndRotation(eyePose.position, eyePose.rotation);

                _faceTracker.GetCurrentProjMatrices(eyeCamera.nearClipPlane, eyeCamera.farClipPlane,
                                                    out _currentProjMatrices);
                var projMat = _currentProjMatrices.GetProjectionMatrix(type);

                if (!SRDHelper.HasNanOrInf(projMat))
                {
                    eyeCamera.ResetProjectionMatrix();
                    eyeCamera.fieldOfView      = CalcVerticalFoVFromProjectionMatrix(projMat);
                    eyeCamera.aspect           = CalcAspectWperHFromProjectionMatrix(projMat);
                    eyeCamera.projectionMatrix = projMat;

                    if (_isBoxFrontClippingCache)
                    {
                        var nearClipPlaneTF = _srdManager.DisplayEdges.LeftBottom;
                        eyeCamera.projectionMatrix = CalcObliquedNearClipProjectionMatrix(eyeCamera, nearClipPlaneTF.forward,
                                                                                          nearClipPlaneTF.position + nearClipPlaneTF.forward * ObliquedNearClipOffset * nearClipPlaneTF.lossyScale.x);
                    }
                }

                var homographyMat = SRDHelper.CalcHomographyMatrix(_srdManager.DisplayEdges.LeftUp.position, _srdManager.DisplayEdges.LeftBottom.position,
                                                                   _srdManager.DisplayEdges.RightBottom.position, _srdManager.DisplayEdges.RightUp.position,
                                                                   eyeCamera);
                var invHomographyMat = SRDHelper.CalcInverseMatrix3x3(homographyMat);
                homographyMaterial.SetFloatArray("_Homography", invHomographyMat);
                homographyMaterial.SetFloatArray("_InvHomography", homographyMat);
            };

            if (_isSRPUsed)
            {
#if SRP_AVAILABLE
                SRPCallbackFunc srpCallback = (context, camera) =>
                {
                    if (camera.name != eyeCamera.name)
                    {
                        return;
                    }
                    updateState(camera);
                };
                _eyeCamSRPPreCallback[type] = srpCallback;
                RenderPipelineManager.beginCameraRendering += _eyeCamSRPPreCallback[type];
#endif
            }
            else
            {
                Camera.CameraCallback cameraStateUpdate = (camera) =>
                {
                    if (camera.name != eyeCamera.name)
                    {
                        return;
                    }
                    updateState(camera);
                };
                _eyeCamStateUpdateCallback[type] = cameraStateUpdate;
                // This Should be onPreCull for correct frustum culling, however onPreCull is fired before vblank sometimes.
                // That's why onPreRender is used to make the latency shorter as possible
                Camera.onPreRender += _eyeCamStateUpdateCallback[type];
            }
        }