/// <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"); } } }