private void ConfigureCamera(GameObject node, VRNode eye, HMD_Config hmdConfig) { // adjust camera X-positions based on IPD float xDir = 0; if (eye == VRNode.LeftEye) { xDir = -1; } else if (eye == VRNode.RightEye) { xDir = +1; } // shift camera sideways considering any offset orientation node.transform.localPosition = (node.transform.localRotation * Vector3.right) * ((hmdConfig.IPD / 2) * xDir); foreach (Camera cam in node.GetComponents <Camera>()) { // Setup perspective projection, with aspect ratio matches viewport float top = (float)Mathf.Tan(Mathf.Deg2Rad * hmdConfig.FieldOfView / 2) * cam.nearClipPlane; float bottom = -top; float left = cam.aspect * bottom / 2; float right = -left; // apply centre offset and adapt viewport float offX = hmdConfig.xOffset * (left - right) / 2; if (eye == VRNode.LeftEye) { cam.rect = new Rect(0.0f, 0, 0.5f, 1); } else if (eye == VRNode.RightEye) { cam.rect = new Rect(0.5f, 0, 0.5f, 1); offX = -offX; } else { cam.rect = new Rect(0.0f, 0, 1.0f, 1); offX = 0; } // calculate off-centre projection matrix Matrix4x4 projectionMatrix = cam.projectionMatrix; CalculateProjectionMatrix(ref projectionMatrix, left + offX, right + offX, top, bottom, cam.nearClipPlane, cam.farClipPlane); cam.projectionMatrix = projectionMatrix; // add distortion filter LensDistortion distortion = cam.GetComponent <LensDistortion>(); if (distortion == null) { distortion = cam.gameObject.AddComponent <LensDistortion>(); distortion.DistortionShader = Shader.Find("VR/LensDistortion"); } distortion.ApplyConfig(hmdConfig); distortion.ScaleIn = 1.1f; // TODO: Hardcoded values > calculate automatically distortion.ScaleOut = 0.82f; // TODO: Hardcoded values > calculate automatically } }
private void UpdateCameras() { if (needsCameraConfigure) { // Check presence of any VR display which would take care of the configuration automatically if (UnityEngine.VR.VRSettings.loadedDevice != VRDeviceType.None) { Debug.Log("VR Display: " + UnityEngine.VR.VRDevice.model); needsCameraConfigure = false; } } if (needsCameraConfigure) { // Is there at least one camera component in the children? Camera camera = GetComponentInChildren <Camera>(); if (camera == null) { Debug.LogError("No camera component(s) found in node or in children."); return; } // is this a HMD type? if (config is HMD_Config) { HMD_Config hmdConfig = (HMD_Config)config; // use that game object as template for left/right eye cameraNode = camera.gameObject; leftCameraNode = GameObject.Instantiate(cameraNode); leftCameraNode.name = "Left Eye Camera"; leftCameraNode.transform.parent = cameraNode.transform.parent; leftCameraNode.transform.localRotation = cameraNode.transform.localRotation; leftCameraNode.transform.localScale = Vector3.one; ConfigureCamera(leftCameraNode, VRNode.LeftEye, hmdConfig); rightCameraNode = GameObject.Instantiate(cameraNode); rightCameraNode.name = "Right Eye Camera"; rightCameraNode.transform.parent = cameraNode.transform.parent; rightCameraNode.transform.localRotation = cameraNode.transform.localRotation; rightCameraNode.transform.localScale = Vector3.one; ConfigureCamera(rightCameraNode, VRNode.RightEye, hmdConfig); leftCameraNode.SetActive(true); rightCameraNode.SetActive(true); cameraNode.SetActive(false); } needsCameraConfigure = false; } }
/// <summary> /// Copy parameters from the VR Display configuration structure to the shader. /// </summary> /// <param name="config">the VR Display configuration structure to copy from</param> /// public void ApplyConfig(HMD_Config config) { for (int i = 0; i < 4; i++) { DistortionCoefficients[i] = config.LensDistortionParameters[i]; } for (int i = 0; i < 2; i++) { // from two [2] arrays to one [4] vector ChromaticAberration[i + 0] = config.ChromaticAberrationParametersRed[i]; ChromaticAberration[i + 2] = config.ChromaticAberrationParametersBlue[i]; } }