void Update() { DisplayParameters newDisplay = DisplayParameters.Collect(); UpdateView(HmdParameters.Instance, newDisplay); _hmdParamsDirty = false; _display = newDisplay; }
public static Fov GetFovDistancesLeft(DisplayParameters display, HmdParameters hmd) { float outerDist = 0.5f * (display.Size.x - hmd.InterlensDistance); float innerDist = 0.5f * hmd.InterlensDistance; float bottomDist = hmd.EyeOffsetY; float topDist = display.Size.y - bottomDist; return(new Fov(outerDist, innerDist, bottomDist, topDist)); }
void OnEnable() { _display = null; _camWorldLeft = GetComponentsInChildren <Camera>().First(cam => cam.stereoTargetEye == StereoTargetEyeMask.Left); _camWorldRight = GetComponentsInChildren <Camera>().First(cam => cam.stereoTargetEye == StereoTargetEyeMask.Right); _camWorldLeft.transform.localRotation = Quaternion.identity; _camWorldRight.transform.localRotation = Quaternion.identity; _undistortionTex = new Texture2D(texWidth, 1, TextureFormat.RGB24, false, true); _undistortionTex.filterMode = FilterMode.Bilinear; _undistortionTex.wrapMode = TextureWrapMode.Clamp; HmdParameters.Instance.ParamsChanged.AddListener(OnHmdParamsChanged); }
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)); }
void OnRenderImage(RenderTexture source, RenderTexture destination) { UpdateView(HmdParameters.Instance, DisplayParameters.Collect()); Graphics.Blit(RenderTexture, destination, EyeMaterial); }