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();
            }
        }
Пример #2
0
        /////////////////////////////////////////////////////////////////////////////////
        // 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;
            }
        }