Example #1
0
        /// <summary>
        ///     Renders the view of a given Renderer as if it were through another renderer. Returns true if successful.
        /// </summary>
        /// <param name="headCam">The origin camera</param>
        /// <param name="material">The Material to modify</param>
        /// <param name="sourceRenderer">The Source renderer</param>
        /// <param name="targetRenderer">The Target renderer</param>
        /// <param name="mesh">The Mesh of the source Renderer</param>
        /// <param name="obliquePlane">Will the projection matrix be clipped at the near plane?</param>
        /// <param name="is3d">Is the renderer not being treated as two-dimenstional?</param>
        /// <param name="isMirror">Is the renderer rendering through itself?</param>
        /// <param name="isSSR">Is the renderer a low quality effect renderer, similar to ssr?</param>
        public bool RenderIntoMaterial(Camera headCam, Material material, MeshRenderer sourceRenderer,
                                       MeshRenderer targetRenderer, Mesh mesh, bool obliquePlane = true, bool is3d = false, bool isMirror = false,
                                       bool isSSR = false)
        {
            if (!Initialized)
            {
                return(false);
            }
#if !SKS_VR
            headCam.stereoTargetEye = StereoTargetEyeMask.None;
#endif

            _renderDataTemplate           = RenderDataTemplate;
            RenderDataTemplate.ScreenSize = new Vector2(MainCamera.pixelWidth, MainCamera.pixelHeight);
#if !SKS_PORTALS
//if (camera.transform.parent == transform.parent)
//    return;
#endif

            var firstRender     = false;
            var renderingCamera = RecursionCams[CurrentDepth];

            //Render Placeholder if max depth hit
            if (CurrentDepth > SKSGlobalRenderSettings.RecursionNumber)
            {
                return(false);
            }

            var renderTarget = headCam.targetTexture;
            var marker       = CameraMarker.GetMarker(headCam);

            if (marker)
            {
                if (marker.Owner == OtherCamera)
                {
                    return(false);
                }
            }

            Graphics.SetRenderTarget(renderTarget);

            //Sets up the Render Properties for this render
            var renderProps = new RenderProperties();

            //Is this the first time that the IsMirror is being rendered this frame?
            if (headCam == MainCamera)
            {
                firstRender = true;
            }

            renderProps |= firstRender ? RenderProperties.FirstRender : 0;
            //todo: reenable
            renderProps |= RenderProperties.Optimize;
            renderProps |= CurrentDepth < 1
                ? (obliquePlane ? RenderProperties.ObliquePlane : 0)
                : RenderProperties.ObliquePlane;
            renderProps |= isMirror ? RenderProperties.Mirror : 0;
            renderProps |= isSSR ? RenderProperties.IsSSR : 0;
            renderProps |= SKSGlobalRenderSettings.CustomSkybox ? RenderProperties.RipCustomSkybox : 0;
            renderProps |= SKSGlobalRenderSettings.AggressiveRecursionOptimization
                ? RenderProperties.AggressiveOptimization
                : 0;
            if (firstRender)
            {
                renderProps |= SKSGlobalRenderSettings.Inverted ? RenderProperties.InvertedCached : 0;
                renderProps |= SKSGlobalRenderSettings.UvFlip ? RenderProperties.UvFlipCached : 0;
            }

#if SKS_VR
            renderProps |= RenderProperties.VR;
            renderProps |= SKSGlobalRenderSettings.SinglePassStereo ? RenderProperties.SinglePass : 0;
#endif
            //renderProps &= ~RenderProperties.Optimize;
            _recursionNumber++;

            //Renders the IsMirror itself to the rendertexture
            transform.SetParent(RenderingCameraParent);

            CurrentDepth++;

            renderingCamera.renderingPath = headCam.renderingPath;
            renderingCamera.cullingMask   = headCam.cullingMask;
            renderingCamera.cullingMask  |= 1 << Keywords.Layers.CustomRendererOnly;

            renderingCamera.stereoTargetEye = StereoTargetEyeMask.None;

            renderingCamera.enabled = false;
            RenderingCameras.Add(headCam);

            //Set up the RenderData for the current frame
            RenderDataTemplate.OriginCamera    = headCam;
            RenderDataTemplate.RenderingCamera = renderingCamera;
            RenderDataTemplate.CurrentDepth    = CurrentDepth;

            //Copy per-frame values
            for (var i = 0; i < (int)TextureTargetEye.Count; i++)
            {
                RenderDataTemplate.RenderDataCache[i].CopyFrameData(RenderDataTemplate);
            }
#if SKS_VR
//Stereo Rendering
            if (headCam.stereoTargetEye == StereoTargetEyeMask.Both)
            {
                RenderingCameraParent.rotation = DestinationTransform.rotation *
                                                 (Quaternion.Inverse(OriginTransform.rotation) *
                                                  (headCam.transform.rotation));


                //Todo: Figure out why this optimization doesn't work in VR mode
                //var tempDataLeft = RenderDataTemplate.RenderDataCache[(int)TextureTargetEye.Left];
                //var tempDataRight = RenderDataTemplate.RenderDataCache[(int)TextureTargetEye.Right];
                var tempDataLeft  = RenderDataTemplate.Clone();
                var tempDataRight = RenderDataTemplate.Clone();

                //Left eye
                tempDataLeft.Position         = -SkvrEyeTracking.EyeOffset(headCam);
                tempDataLeft.ProjectionMatrix = headCam.GetStereoProjectionMatrix(Camera.StereoscopicEye.Left);
                tempDataLeft.TargetEye        = TextureTargetEye.Left;
                tempDataLeft.RenderProperties = renderProps;
                _cameraLib.RenderCamera(tempDataLeft);
                Debug.DrawRay(tempDataLeft.Position, headCam.transform.forward, Color.magenta, 1);
                //Right eye
                tempDataRight.Position         = SkvrEyeTracking.EyeOffset(headCam);
                tempDataRight.ProjectionMatrix = headCam.GetStereoProjectionMatrix(Camera.StereoscopicEye.Right);
                tempDataRight.TargetEye        = TextureTargetEye.Right;
                tempDataRight.RenderProperties = renderProps;
                //Debug.DrawRay(tempDataRight.Position, headCam.transform.forward, Color.cyan, 1);

                if (!SKSGlobalRenderSettings.SinglePassStereo)
                {
                    _cameraLib.RenderCamera(tempDataRight);
                }
                else
                {
                    renderingCamera.stereoTargetEye = StereoTargetEyeMask.Right;
                    _cameraLib.RenderCamera(tempDataRight);
                }
            }

            else
            {
                //Non-VR rendering with VR enabled
                //Todo: Figure out why this optimization doesn't work in VR mode

                /*
                 * var tempData =
                 *  RenderDataTemplate.RenderDataCache[
                 *      (int)TextureTargetEyeMethods.StereoTargetToTextureTarget(
                 *          renderingCamera.stereoTargetEye
                 *          )
                 *  ];*/
                var tempData = RenderDataTemplate.Clone();

                renderProps &= ~RenderProperties.SinglePass;
                renderProps &= ~RenderProperties.VR;

                tempData.RenderProperties          = renderProps;
                renderingCamera.transform.rotation = DestinationTransform.rotation *
                                                     (Quaternion.Inverse(OriginTransform.rotation) *
                                                      (headCam.transform.rotation));

                tempData.ProjectionMatrix = headCam.projectionMatrix;
                tempData.Position         = renderingCamera.transform.position;

                if (renderingCamera.stereoTargetEye == StereoTargetEyeMask.Left)
                {
                    tempData.TargetEye = TextureTargetEye.Left;
                    _cameraLib.RenderCamera(tempData);
                }
                else
                {
                    tempData.TargetEye = TextureTargetEye.Right;
                    _cameraLib.RenderCamera(tempData);
                }
            }
#else
            //Non-stereo rendering
            //RenderData.Position = camera.transform.position;
            var tempData = RenderDataTemplate.RenderDataCache[(int)TextureTargetEye.Right];
            tempData.ProjectionMatrix          = headCam.projectionMatrix;
            tempData.RenderProperties          = renderProps;
            renderingCamera.transform.rotation = DestinationTransform.rotation *
                                                 (Quaternion.Inverse(OriginTransform.rotation) *
                                                  headCam.transform.rotation);
            CameraLib.RenderCamera(tempData);
#endif
            CurrentDepth--;

            RenderingCameras.Remove(headCam);
            if (RenderingCameras.Count == 0)
            {
                try {
                    //_cameraLib.TerminateRender();
                    //SKSRenderLib.ClearUnwinder();
                }
                catch (NullReferenceException e) {
                    Debug.LogWarning("Attempted to render without proper setup");
                }
            }

            return(true);
        }
        /// <summary>
        /// Renders the view of a given Renderer as if it were through another renderer
        /// </summary>
        /// <param name="camera">The origin camera</param>
        /// <param name="material">The Material to modify</param>
        /// <param name="sourceRenderer">The Source renderer</param>
        /// <param name="targetRenderer">The Target renderer</param>
        /// <param name="mesh">The Mesh of the source Renderer</param>
        /// <param name="obliquePlane">Will the projection matrix be clipped at the near plane?</param>
        /// <param name="is3d">Is the renderer not being treated as two-dimenstional?</param>
        /// <param name="isMirror">Is the renderer rendering through itself?</param>
        public void RenderIntoMaterial(Camera camera, Material material, MeshRenderer sourceRenderer, MeshRenderer targetRenderer, Mesh mesh, bool obliquePlane = true, bool is3d = false, bool isMirror = false, bool isSSR = false)
        {
            _renderData = RenderData;
            if (!Initialized)
            {
                return;
            }
#if !SKS_Portals
            //if (camera.transform.parent == transform.parent)
            //    return;
#endif

            bool   firstRender     = false;
            Camera renderingCamera = RecursionCams[CurrentDepth];
            Camera currentCamera   = camera;

            //Render Placeholder if max depth hit
            if (CurrentDepth > SKSGlobalRenderSettings.RecursionNumber)
            {
                return;
            }

            RenderTexture renderTarget = camera.targetTexture;
            CameraMarker  marker       = CameraMarker.GetMarker(camera);

            if (marker)
            {
                // marker.CurrentRenderer = sourceRenderer;
                if (marker.Owner == OtherCamera)
                {
                    return;
                }
            }

            Graphics.SetRenderTarget(renderTarget);

            //Sets up the Render Properties for this render
            RenderProperties renderProps = new RenderProperties();

            //Is this the first time that the IsMirror is being rendered this frame?
            if (camera == Camera.main)
            {
                firstRender = true;
            }
            GUIStyle style = new GUIStyle();
            style.normal.textColor = Color.red;
            renderProps           |= firstRender ? RenderProperties.FirstRender : 0;
            renderProps           |= RenderProperties.Optimize;
            renderProps           |= (CurrentDepth < 1) ? (obliquePlane ? RenderProperties.ObliquePlane : 0) : RenderProperties.ObliquePlane;
            renderProps           |= isMirror ? RenderProperties.Mirror : 0;
            renderProps           |= isSSR ? RenderProperties.IsSSR : 0;
            renderProps           |= SKSGlobalRenderSettings.CustomSkybox ? RenderProperties.RipCustomSkybox : 0;
            renderProps           |= SKSGlobalRenderSettings.AggressiveRecursionOptimization
                ? RenderProperties.AggressiveOptimization
                : 0;
            if (firstRender)
            {
                renderProps |= SKSGlobalRenderSettings.Inverted ? RenderProperties.InvertedCached : 0;
                renderProps |= SKSGlobalRenderSettings.UvFlip ? RenderProperties.UvFlipCached : 0;
            }

#if SKS_VR
            renderProps |= RenderProperties.VR;
            renderProps |= SKSGlobalRenderSettings.SinglePassStereo ? RenderProperties.SinglePass : 0;
#endif

            _recursionNumber++;


            //Renders the IsMirror itself to the rendertexture
            transform.SetParent(RenderingCameraParent);

            CurrentDepth++;

            renderingCamera.renderingPath   = camera.renderingPath;
            renderingCamera.cullingMask     = camera.cullingMask;
            renderingCamera.stereoTargetEye = StereoTargetEyeMask.None;
            renderingCamera.enabled         = false;
            RenderingCameras.Add(camera);


            //Set up the RenderData for the current frame
            RenderData.Camera          = camera;
            RenderData.RenderingCamera = renderingCamera;
            RenderData.CurrentDepth    = CurrentDepth;

#if SKS_VR
            //Stereo Rendering
            if (camera.stereoTargetEye == StereoTargetEyeMask.Both)
            {
                RenderingCameraParent.rotation = DestinationTransform.rotation *
                                                 (Quaternion.Inverse(OriginTransform.rotation) *
                                                  (camera.transform.rotation));

                RenderData tempDataLeft  = RenderData.Clone();
                RenderData tempDataRight = RenderData.Clone();

                //Left eye


                tempDataLeft.Position         = -SKVREyeTracking.EyeOffset(camera);
                tempDataLeft.ProjectionMatrix = camera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Left);
                tempDataLeft.TextureName      = "_LeftEyeTexture";
                tempDataLeft.RenderProperties = renderProps;
                tempDataLeft.Eye = false;
                _cameraLib.RenderCamera(tempDataLeft);

                //Right eye

                tempDataRight.Position         = SKVREyeTracking.EyeOffset(camera);
                tempDataRight.ProjectionMatrix = camera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Right);
                tempDataRight.TextureName      = "_RightEyeTexture";
                tempDataRight.RenderProperties = renderProps;
                tempDataRight.Eye = true;
                if (!SKSGlobalRenderSettings.SinglePassStereo)
                {
                    _cameraLib.RenderCamera(tempDataRight);
                }
                else
                {
                    renderingCamera.stereoTargetEye = StereoTargetEyeMask.Right;
                    _cameraLib.RenderCamera(tempDataRight);
                }
            }

            else
            {
                //Non-VR rendering with VR enabled

                RenderData tempData = RenderData.Clone();
                renderProps &= ~RenderProperties.SinglePass;
                renderProps &= ~RenderProperties.VR;

                tempData.RenderProperties          = renderProps;
                renderingCamera.transform.rotation = DestinationTransform.rotation *
                                                     (Quaternion.Inverse(OriginTransform.rotation) *
                                                      (camera.transform.rotation));

                tempData.ProjectionMatrix = camera.projectionMatrix;
                tempData.Position         = renderingCamera.transform.position;

                if (renderingCamera.stereoTargetEye == StereoTargetEyeMask.Left)
                {
                    tempData.TextureName = "_LeftEyeTexture";
                    tempData.Eye         = false;
                    _cameraLib.RenderCamera(tempData);
                }
                else
                {
                    tempData.TextureName = "_RightEyeTexture";
                    tempData.Eye         = true;
                    _cameraLib.RenderCamera(tempData);
                }
            }
#else
            //Non-stereo rendering
            //RenderData.Position = camera.transform.position;
            RenderData tempData = RenderData.Clone();

            tempData.ProjectionMatrix = camera.projectionMatrix;
            tempData.TextureName      = "_RightEyeTexture";
            tempData.RenderProperties = renderProps;

            tempData.Eye = true;


            renderingCamera.transform.rotation = DestinationTransform.rotation * (Quaternion.Inverse(OriginTransform.rotation) * (camera.transform.rotation));
            CameraLib.RenderCamera(tempData);
#endif
            SKEffectCamera.CurrentDepth--;

            RenderingCameras.Remove(camera);
            if (RenderingCameras.Count == 0)
            {
                try {
                    _cameraLib.TerminateRender();
                    //SKSRenderLib.ClearUnwinder();
                }
                catch (NullReferenceException e) {
                    Debug.LogWarning("Attempted to render without proper setup");
                }
            }
        }