public void Render(VRRenderEventDetector detector) { // move stereo camera around based on HMD pose MoveStereoCameraBasedOnHmdPose(detector); // invoke pre-render events if (preRenderListeners != null) { preRenderListeners.Invoke(); } if (canvasVisible) { // change layer of specified objects, // so that they become invisible to currect camera ignoreObjOriginalLayer.Clear(); for (int i = 0; i < ignoreWhenRender.Count; i++) { ignoreObjOriginalLayer.Add(ignoreWhenRender[i].layer); } // invert backface culling when rendering a mirror if (isMirror) { GL.invertCulling = true; } // render the canvas RenderToTwoStereoTextures(detector); // reset backface culling if (isMirror) { GL.invertCulling = false; } // resume object layers for (int i = 0; i < ignoreWhenRender.Count; i++) { ignoreWhenRender[i].layer = ignoreObjOriginalLayer[i]; } // finish this render pass, reset visibility canvasVisible = false; } // invoke post-render events if (postRenderListeners != null) { postRenderListeners.Invoke(); } }
///////////////////////////////////////////////////////////////////////////////// // render related public void InvokeStereoRenderers(VRRenderEventDetector detector) { // render registored stereo cameras for (int renderIter = 0; renderIter < stereoRenderers.Count; renderIter++) { StereoRenderer stereoRenderer = stereoRenderers[renderIter]; if (stereoRenderer.shouldRender) { stereoRenderer.Render(detector); } } }
private void RenderToTwoStereoTextures(VRRenderEventDetector detector) { float ipd = 0.06567926f; var leftEyeOffset = new Vector3(-ipd / 2, 0, 0); var rightEyeOffset = new Vector3(ipd / 2, 0, 0); int hash = detector.GetHashCode(); int renderWidth = (int)(textureResolutionScale * detector.Camera.pixelWidth); int renderHeight = (int)(textureResolutionScale * detector.Camera.pixelHeight); if (!leftEyeTextures.ContainsKey(hash)) { leftEyeTextures.Add(hash, CreateRenderTexture(renderWidth, renderHeight)); } if (!rightEyeTextures.ContainsKey(hash)) { rightEyeTextures.Add(hash, CreateRenderTexture(renderWidth, renderHeight)); } Matrix4x4 leftProjectionMatrix = detector.Camera.projectionMatrix; Matrix4x4 rightProjectionMatrix = detector.Camera.projectionMatrix; if (detector.Camera.stereoEnabled) { leftProjectionMatrix = detector.Camera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Left); rightProjectionMatrix = detector.Camera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Right); } // render stereo textures RenderEye( leftEyeOffset, leftProjectionMatrix, detector.Camera.worldToCameraMatrix, leftEyeTextures[hash], "_LeftEyeTexture"); if (detector.Camera.stereoEnabled) { var rightEyeWorldToCameraMatrix = detector.Camera.worldToCameraMatrix; rightEyeWorldToCameraMatrix.m03 -= ipd; RenderEye( rightEyeOffset, rightProjectionMatrix, rightEyeWorldToCameraMatrix, rightEyeTextures[hash], "_RightEyeTexture"); } }
public void MoveStereoCameraBasedOnHmdPose(VRRenderEventDetector detector) { Vector3 mainCamPos = detector.transform.position; Quaternion mainCamRot = detector.transform.rotation; if (isMirror) { // get reflection plane -- assume +y as normal float d = -Vector3.Dot(canvasOriginUp, canvasOriginPos); Vector4 reflectionPlane = new Vector4(canvasOriginUp.x, canvasOriginUp.y, canvasOriginUp.z, d); // get reflection matrix reflectionMat = Matrix4x4.zero; CalculateReflectionMatrix(ref reflectionMat, reflectionPlane); // set head position Vector3 reflectedPos = reflectionMat.MultiplyPoint(mainCamPos); stereoCameraHead.transform.position = reflectedPos; // set head orientation stereoCameraHead.transform.rotation = mainCamRot; } else { Vector3 posCanvasToMainCam = mainCamPos - canvasOriginPos; // compute the rotation between the portal entry and the portal exit Quaternion rotCanvasToAnchor = anchorRot * Quaternion.Inverse(canvasOriginRot); // move remote camera position Vector3 posAnchorToStereoCam = rotCanvasToAnchor * posCanvasToMainCam; stereoCameraHead.transform.position = anchorPos + posAnchorToStereoCam; // rotate remote camera stereoCameraHead.transform.rotation = rotCanvasToAnchor * mainCamRot; } }