static void DrawerOutputMultiDisplay(UniversalRenderPipelineSerializedCamera p, Editor owner) { using (var checkScope = new EditorGUI.ChangeCheckScope()) { p.baseCameraSettings.DrawMultiDisplay(); if (checkScope.changed) { UpdateStackCamerasOutput(p, camera => { bool isChanged = false; // Force same target display int targetDisplay = p.baseCameraSettings.targetDisplay.intValue; if (camera.targetDisplay != targetDisplay) { camera.targetDisplay = targetDisplay; isChanged = true; } // Force same target display StereoTargetEyeMask stereoTargetEye = (StereoTargetEyeMask)p.baseCameraSettings.targetEye.intValue; if (camera.stereoTargetEye != stereoTargetEye) { camera.stereoTargetEye = stereoTargetEye; isChanged = true; } return(isChanged); }); } } }
private bool ShouldRenderRightEye(Camera cam) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) StereoTargetEyeMask stereoTargetEye = cam.get_stereoTargetEye(); bool flag = (int)stereoTargetEye == 3 || (int)stereoTargetEye == 2; if (!flag) { return(false); } if (Vector3.Dot(GetWorldEyePos(cam, 1) - this.get_transform().get_position(), GetNormalDirection()) <= 0f) { flag = false; } return(flag); }
private bool IsStackCameraOutputDirty(Camera camera) { // Force same render texture RenderTexture targetTexture = settings.targetTexture.objectReferenceValue as RenderTexture; if (camera.targetTexture != targetTexture) { return(true); } // Force same hdr bool allowHDR = settings.HDR.boolValue; if (camera.allowHDR != allowHDR) { return(true); } // Force same mssa bool allowMSSA = settings.allowMSAA.boolValue; if (camera.allowMSAA != allowMSSA) { return(true); } // Force same viewport rect Rect rect = settings.normalizedViewPortRect.rectValue; if (camera.rect != rect) { return(true); } // Force same dynamic resolution bool allowDynamicResolution = settings.allowDynamicResolution.boolValue; if (camera.allowDynamicResolution != allowDynamicResolution) { return(true); } // Force same target display int targetDisplay = settings.targetDisplay.intValue; if (camera.targetDisplay != targetDisplay) { return(true); } // Force same target display StereoTargetEyeMask stereoTargetEye = (StereoTargetEyeMask)settings.targetEye.intValue; if (camera.stereoTargetEye != stereoTargetEye) { return(true); } return(false); }
public RenderTexture GetRT(StereoTargetEyeMask eye) { #if USE_2RT return((eye == StereoTargetEyeMask.Left) ? ColorDepthLRT[delayFrame] : ColorDepthRRT[delayFrame]); #else return(ColorDepthLRT[delayFrame]); #endif }
private void CameraPostRender(Camera camera) { if (currentRenderTextures.Count != 0) { int idx = currentRenderTextures.Count - 1; KeyValuePair <RenderTexture, RenderTexture> kv = currentRenderTextures[idx]; ReflectRenderer.sharedMaterial.SetTexture(ReflectionSamplerName, kv.Key); ReflectRenderer.sharedMaterial.SetTexture(ReflectionSamplerName2, kv.Value); currentRenderTextures.RemoveAt(idx); } for (int i = currentCameras.Count - 1; i >= 0; i--) { if (currentCameras[i].SourceCamera == camera) { CleanupCamera(currentCameras[i], false); currentCameras.RemoveAt(i); } } List <KeyValuePair <RenderTexture, StereoTargetEyeMask> > texturesToRelease; if (sourceCamerasToRenderTextures.TryGetValue(camera, out texturesToRelease)) { // free up temporary render textures // if in multi-pass, we only free the texture for the current rendering eye // if in single-pass, we free them all StereoTargetEyeMask mask = StereoTargetEyeMask.Both; string tmp; bool isReflectionCamera = CameraIsReflection(camera, out tmp); for (int i = texturesToRelease.Count - 1; i >= 0; i--) { // if reflection or multi-pass, use camera eye, else free all textures if (isReflectionCamera || UnityEngine.XR.XRDevice.isPresent && UnityEngine.XR.XRSettings.eyeTextureDesc.vrUsage == VRTextureUsage.OneEye) { switch (camera.stereoActiveEye) { default: mask = StereoTargetEyeMask.Both; break; case Camera.MonoOrStereoscopicEye.Left: mask = StereoTargetEyeMask.Left; break; case Camera.MonoOrStereoscopicEye.Right: mask = StereoTargetEyeMask.Right; break; } } KeyValuePair <RenderTexture, StereoTargetEyeMask> tex = texturesToRelease[i]; if (tex.Key != null && (mask & tex.Value) != StereoTargetEyeMask.None) { RenderTexture.ReleaseTemporary(tex.Key); texturesToRelease.RemoveAt(i); } } } }
private void CameraPostRender(Camera camera) { if (currentRenderTextures.Count != 0) { int idx = currentRenderTextures.Count - 1; KeyValuePair <RenderTexture, RenderTexture> kv = currentRenderTextures[idx]; ReflectRenderer.sharedMaterial.SetTexture(ReflectionSamplerName, kv.Key); ReflectRenderer.sharedMaterial.SetTexture(ReflectionSamplerName2, kv.Value); currentRenderTextures.RemoveAt(idx); } for (int i = currentCameras.Count - 1; i >= 0; i--) { if (currentCameras[i].SourceCamera == camera) { CleanupCamera(currentCameras[i], false); currentCameras.RemoveAt(i); } } List <KeyValuePair <RenderTexture, StereoTargetEyeMask> > texturesToRelease; if (sourceCamerasToRenderTextures.TryGetValue(camera, out texturesToRelease)) { // free up temporary render textures // if in multi-pass, we only free the texture for the current rendering eye // if in single-pass, we free them all StereoTargetEyeMask mask = StereoTargetEyeMask.Both; for (int i = texturesToRelease.Count - 1; i >= 0; i--) { if (!singlePassStereo) { switch (camera.stereoActiveEye) { default: mask = StereoTargetEyeMask.Both; break; case Camera.MonoOrStereoscopicEye.Left: mask = StereoTargetEyeMask.Left; break; case Camera.MonoOrStereoscopicEye.Right: mask = StereoTargetEyeMask.Right; break; } } KeyValuePair <RenderTexture, StereoTargetEyeMask> tex = texturesToRelease[i]; if (tex.Key != null && (mask & tex.Value) != StereoTargetEyeMask.None) { if (tex.Key.IsCreated()) { tex.Key.Release(); GameObject.DestroyImmediate(tex.Key); } texturesToRelease.RemoveAt(i); } } } }
private void unlockLeftEye() { eye = StereoTargetEyeMask.Left; observables.ApplyCommandsToLeftSide(); cameraRig.SetLeftEyeRotationAndPosition(); cameraRig.StraightenRightEye(); cameraRig.SetRightEyePositionOnly(); }
public void SwapTargetEye() { if (targetEye == StereoTargetEyeMask.Left) { targetEye = StereoTargetEyeMask.Right; } else { targetEye = StereoTargetEyeMask.Left; } }
void toggleARCamera() { if (mode == StereoTargetEyeMask.Both) // switching to normal mode { mode = StereoTargetEyeMask.None; MixedRealityController.Instance.SetMode(MixedRealityController.Mode.HANDHELD_AR); } else // switching to AR mode { mode = StereoTargetEyeMask.Both; MixedRealityController.Instance.SetMode(MixedRealityController.Mode.VIEWER_AR); } }
void Start() { arcamera = GameObject.Find("ARCamera"); button = GameObject.Find("Button").GetComponent <Button>(); button.onClick.AddListener(toggleARCamera); mode = StereoTargetEyeMask.None; MixedRealityController.Instance.SetMode(MixedRealityController.Mode.HANDHELD_AR); if (arcamera != null) { camera = arcamera.GetComponent("Camera") as Camera; Debug.Log(camera); } CameraDevice.Instance.SetFrameFormat(Vuforia.Image.PIXEL_FORMAT.RGB888, true); }
private void FetchEyeCalibration() { if (cameraRig.config.rightEyeIsStrabismic) { eyeMask = StereoTargetEyeMask.Right; misalignmentRotation = cameraRig.config.rightEyeMisalignmentAngle; } else { //default to left eye eyeMask = StereoTargetEyeMask.Left; misalignmentRotation = cameraRig.config.leftEyeMisalignmentAngle; } }
// Shifts the camera to the according side (depending on eye and if eyes are inverted) by the half eye distance. // If shiftEyeSide is set to Both or None, the camera is placed in the center. private void ShiftCamera(StereoTargetEyeMask shiftEyeSide) { float shiftMul = 0f; if (shiftEyeSide == StereoTargetEyeMask.Right) { shiftMul = 1.0f; } else if (shiftEyeSide == StereoTargetEyeMask.Left) { shiftMul = -1.0f; } _cam.transform.localPosition = Vector3.right * _stereoSeparation * 0.5f * shiftMul; }
protected override void ReadFromImpl(object obj) { base.ReadFromImpl(obj); Camera uo = (Camera)obj; nearClipPlane = uo.nearClipPlane; farClipPlane = uo.farClipPlane; fieldOfView = uo.fieldOfView; renderingPath = uo.renderingPath; allowHDR = uo.allowHDR; allowMSAA = uo.allowMSAA; allowDynamicResolution = uo.allowDynamicResolution; forceIntoRenderTexture = uo.forceIntoRenderTexture; orthographicSize = uo.orthographicSize; orthographic = uo.orthographic; opaqueSortMode = uo.opaqueSortMode; transparencySortMode = uo.transparencySortMode; transparencySortAxis = uo.transparencySortAxis; depth = uo.depth; aspect = uo.aspect; cullingMask = uo.cullingMask; eventMask = uo.eventMask; layerCullSpherical = uo.layerCullSpherical; cameraType = uo.cameraType; layerCullDistances = uo.layerCullDistances; useOcclusionCulling = uo.useOcclusionCulling; cullingMatrix = uo.cullingMatrix; backgroundColor = uo.backgroundColor; clearFlags = uo.clearFlags; depthTextureMode = uo.depthTextureMode; clearStencilAfterLightingPass = uo.clearStencilAfterLightingPass; usePhysicalProperties = uo.usePhysicalProperties; sensorSize = uo.sensorSize; lensShift = uo.lensShift; focalLength = uo.focalLength; rect = uo.rect; pixelRect = uo.pixelRect; targetTexture = ToID(uo.targetTexture); targetDisplay = uo.targetDisplay; worldToCameraMatrix = uo.worldToCameraMatrix; projectionMatrix = uo.projectionMatrix; nonJitteredProjectionMatrix = uo.nonJitteredProjectionMatrix; useJitteredProjectionMatrixForTransparentRendering = uo.useJitteredProjectionMatrixForTransparentRendering; scene = uo.scene; stereoSeparation = uo.stereoSeparation; stereoConvergence = uo.stereoConvergence; stereoTargetEye = uo.stereoTargetEye; }
protected void unlockLeftEye() { eye = StereoTargetEyeMask.Left; cameraRig.SetLeftEyeRotationAndPosition(); cameraRig.config.leftEyeIsStrabismic = true; cameraRig.config.rightEyeIsStrabismic = false; cameraRig.config.Sync(); rightEyeIsStrabismic = false; // relock right eye cameraRig.StraightenRightEye(); cameraRig.SetRightEyePositionOnly(); }
// Creates a new CAVE camera to render to a specific screen. public Camera AddCamera(StereoTargetEyeMask targetEye, int displayIndex, Transform parent, GameObject targetPlane) { // Create a camera and update it's settings. GameObject camera = new GameObject("Display" + displayIndex + "_" + targetEye.ToString()); camera.transform.parent = parent; camera.transform.localPosition = Vector3.zero; camera.transform.localRotation = Quaternion.identity; Camera camComponent = camera.AddComponent <Camera>(); camComponent.stereoTargetEye = targetEye; camComponent.targetDisplay = displayIndex; camera.AddComponent <CAVEScreen>().projectionScreen = targetPlane; return(camComponent); }
public static int GetDepthSliceForEye(StereoTargetEyeMask mask) { switch (mask) { case StereoTargetEyeMask.Both: return(-1); case StereoTargetEyeMask.None: case StereoTargetEyeMask.Left: return(0); case StereoTargetEyeMask.Right: return(1); default: throw new ArgumentException("Unknown mode"); } }
private void SetupCubemapOnCameras(StereoCubemap newCubemap) { activeCubemap = newCubemap; foreach (Camera cam in CAVECameraRig.allCameras) { // Debug.Log("Setting material for Camera " + cam.name); StereoTargetEyeMask targetEye = cam.stereoTargetEye; Material skyboxMaterial = newCubemap.rightEyeCubemap; if (targetEye == StereoTargetEyeMask.Left) { // Debug.Log("Setting material for left eye Camera: " + cam.name); skyboxMaterial = newCubemap.leftEyeCubemap; } Skybox camSkybox = cam.GetComponent <Skybox>(); if (camSkybox == null) { camSkybox = cam.gameObject.AddComponent <Skybox>(); } camSkybox.material = skyboxMaterial; camSkybox.enabled = true; if (skyboxMaterial == null) { //Debug.LogError("No skybox material found for Camera " + cam.name); } } Debug.Log("Added Cubemaps"); Set3D(CAVECameraRig.is3D); PlatformMonitor.SetMonitorText(newCubemap.text); }
public static void TakeStereoScreenshot(uint screenshotHandle, GameObject target, int cellSize, float ipd, ref string previewFilename, ref string VRFilename) { Texture2D texture2D = new Texture2D(4096, 4096, TextureFormat.ARGB32, false); Stopwatch stopwatch = new Stopwatch(); Camera camera = null; stopwatch.Start(); Camera camera2 = target.GetComponent <Camera>(); if (camera2 == null) { if (camera == null) { camera = new GameObject().AddComponent <Camera>(); } camera2 = camera; } Texture2D texture2D2 = new Texture2D(2048, 2048, TextureFormat.ARGB32, false); RenderTexture renderTexture = new RenderTexture(2048, 2048, 24); RenderTexture targetTexture = camera2.targetTexture; bool orthographic = camera2.orthographic; float fieldOfView = camera2.fieldOfView; float aspect = camera2.aspect; StereoTargetEyeMask stereoTargetEye = camera2.stereoTargetEye; camera2.stereoTargetEye = StereoTargetEyeMask.None; camera2.fieldOfView = 60f; camera2.orthographic = false; camera2.targetTexture = renderTexture; camera2.aspect = 1f; camera2.Render(); RenderTexture.active = renderTexture; texture2D2.ReadPixels(new Rect(0f, 0f, (float)renderTexture.width, (float)renderTexture.height), 0, 0); RenderTexture.active = null; camera2.targetTexture = null; UnityEngine.Object.DestroyImmediate(renderTexture); SteamVR_SphericalProjection steamVR_SphericalProjection = camera2.gameObject.AddComponent <SteamVR_SphericalProjection>(); Vector3 localPosition = target.transform.localPosition; Quaternion localRotation = target.transform.localRotation; Vector3 position = target.transform.position; Quaternion lhs = Quaternion.Euler(0f, target.transform.rotation.eulerAngles.y, 0f); Transform transform = camera2.transform; int num = 1024 / cellSize; float num2 = 90f / (float)num; float num3 = num2 / 2f; RenderTexture renderTexture2 = new RenderTexture(cellSize, cellSize, 24); renderTexture2.wrapMode = TextureWrapMode.Clamp; renderTexture2.antiAliasing = 8; camera2.fieldOfView = num2; camera2.orthographic = false; camera2.targetTexture = renderTexture2; camera2.aspect = aspect; camera2.stereoTargetEye = StereoTargetEyeMask.None; for (int i = 0; i < num; i++) { float num4 = 90f - (float)i * num2 - num3; int num5 = 4096 / renderTexture2.width; float num6 = 360f / (float)num5; float num7 = num6 / 2f; int num8 = i * 1024 / num; for (int j = 0; j < 2; j++) { if (j == 1) { num4 = -num4; num8 = 2048 - num8 - cellSize; } for (int k = 0; k < num5; k++) { float num9 = -180f + (float)k * num6 + num7; int destX = k * 4096 / num5; int num10 = 0; float num11 = -ipd / 2f * Mathf.Cos(num4 * 0.017453292f); for (int l = 0; l < 2; l++) { if (l == 1) { num10 = 2048; num11 = -num11; } Vector3 b = lhs * Quaternion.Euler(0f, num9, 0f) * new Vector3(num11, 0f, 0f); transform.position = position + b; Quaternion quaternion = Quaternion.Euler(num4, num9, 0f); transform.rotation = lhs * quaternion; Vector3 vector = quaternion * Vector3.forward; float num12 = num9 - num6 / 2f; float num13 = num12 + num6; float num14 = num4 + num2 / 2f; float num15 = num14 - num2; float y = (num12 + num13) / 2f; float x = (Mathf.Abs(num14) < Mathf.Abs(num15)) ? num14 : num15; Vector3 vector2 = Quaternion.Euler(x, num12, 0f) * Vector3.forward; Vector3 vector3 = Quaternion.Euler(x, num13, 0f) * Vector3.forward; Vector3 vector4 = Quaternion.Euler(num14, y, 0f) * Vector3.forward; Vector3 vector5 = Quaternion.Euler(num15, y, 0f) * Vector3.forward; Vector3 vector6 = vector2 / Vector3.Dot(vector2, vector); Vector3 a = vector3 / Vector3.Dot(vector3, vector); Vector3 vector7 = vector4 / Vector3.Dot(vector4, vector); Vector3 a2 = vector5 / Vector3.Dot(vector5, vector); Vector3 a3 = a - vector6; Vector3 a4 = a2 - vector7; float magnitude = a3.magnitude; float magnitude2 = a4.magnitude; float num16 = 1f / magnitude; float num17 = 1f / magnitude2; Vector3 uAxis = a3 * num16; Vector3 vAxis = a4 * num17; steamVR_SphericalProjection.Set(vector, num12, num13, num14, num15, uAxis, vector6, num16, vAxis, vector7, num17); camera2.aspect = magnitude / magnitude2; camera2.Render(); RenderTexture.active = renderTexture2; texture2D.ReadPixels(new Rect(0f, 0f, (float)renderTexture2.width, (float)renderTexture2.height), destX, num8 + num10); RenderTexture.active = null; } float flProgress = ((float)i * ((float)num5 * 2f) + (float)k + (float)(j * num5)) / ((float)num * ((float)num5 * 2f)); OpenVR.Screenshots.UpdateScreenshotProgress(screenshotHandle, flProgress); } } } OpenVR.Screenshots.UpdateScreenshotProgress(screenshotHandle, 1f); previewFilename += ".png"; VRFilename += ".png"; texture2D2.Apply(); File.WriteAllBytes(previewFilename, ImageConversion.EncodeToPNG(texture2D)); texture2D.Apply(); File.WriteAllBytes(VRFilename, ImageConversion.EncodeToPNG(texture2D)); if (camera2 != camera) { camera2.targetTexture = targetTexture; camera2.orthographic = orthographic; camera2.fieldOfView = fieldOfView; camera2.aspect = aspect; camera2.stereoTargetEye = stereoTargetEye; target.transform.localPosition = localPosition; target.transform.localRotation = localRotation; } else { camera.targetTexture = null; } UnityEngine.Object.DestroyImmediate(renderTexture2); UnityEngine.Object.DestroyImmediate(steamVR_SphericalProjection); stopwatch.Stop(); UnityEngine.Debug.Log(string.Format("Screenshot took {0} seconds.", stopwatch.Elapsed)); if (camera != null) { UnityEngine.Object.DestroyImmediate(camera.gameObject); } UnityEngine.Object.DestroyImmediate(texture2D2); UnityEngine.Object.DestroyImmediate(texture2D); }
private void UpdateStackCameraOutput(Camera camera) { Undo.RecordObject(camera, Styles.inspectorOverlayCameraText); bool isChanged = false; // Force same render texture RenderTexture targetTexture = settings.targetTexture.objectReferenceValue as RenderTexture; if (camera.targetTexture != targetTexture) { camera.targetTexture = targetTexture; isChanged = true; } // Force same hdr bool allowHDR = settings.HDR.boolValue; if (camera.allowHDR != allowHDR) { camera.allowHDR = allowHDR; isChanged = true; } // Force same mssa bool allowMSSA = settings.allowMSAA.boolValue; if (camera.allowMSAA != allowMSSA) { camera.allowMSAA = allowMSSA; isChanged = true; } // Force same viewport rect Rect rect = settings.normalizedViewPortRect.rectValue; if (camera.rect != rect) { camera.rect = settings.normalizedViewPortRect.rectValue; isChanged = true; } // Force same dynamic resolution bool allowDynamicResolution = settings.allowDynamicResolution.boolValue; if (camera.allowDynamicResolution != allowDynamicResolution) { camera.allowDynamicResolution = allowDynamicResolution; isChanged = true; } // Force same target display int targetDisplay = settings.targetDisplay.intValue; if (camera.targetDisplay != targetDisplay) { camera.targetDisplay = targetDisplay; isChanged = true; } // Force same target display todo StereoTargetEyeMask stereoTargetEye = (StereoTargetEyeMask)settings.targetEye.intValue; if (camera.stereoTargetEye != stereoTargetEye) { camera.stereoTargetEye = stereoTargetEye; isChanged = true; } if (isChanged) { EditorUtility.SetDirty(camera); } }
/// <summary> /// Render a reflection camera. Reflection camera should already be setup with a render texture. /// </summary> /// <param name="sourceCamera">Camera source</param> /// <param name="reflectionCamera">Reflection camera</param> /// <param name="reflectionTransform">Reflection transform</param> /// <param name="reflectionNormal">Reflection normal vector</param> /// <param name="eye">Stereo eye mask</param> /// <param name="targetTexture">Target texture</param> private void RenderReflectionInternal ( Camera sourceCamera, Camera reflectionCamera, Transform reflectionTransform, Vector3 reflectionNormal, StereoTargetEyeMask eye, RenderTexture targetTexture ) { bool sourceCameraIsReflection = CameraIsReflection(sourceCamera); bool oldInvertCulling = GL.invertCulling; // find out the reflection plane: position and normal in world space Vector3 pos = reflectionTransform.position; // Render reflection // Reflect camera around reflection plane if (sourceCameraIsReflection && GL.invertCulling) { reflectionNormal = -reflectionNormal; } float d = -Vector3.Dot(reflectionNormal, pos) - ClipPlaneOffset; Vector4 reflectionPlane = new Vector4(reflectionNormal.x, reflectionNormal.y, reflectionNormal.z, d); Matrix4x4 reflection; CalculateReflectionMatrix(out reflection, reflectionPlane); Vector3 origReflectionStartPos = sourceCamera.transform.position; Vector3 reflectionStartPos = origReflectionStartPos; if (ReflectionOffsetFunc != null) { reflectionStartPos = ReflectionOffsetFunc(reflectionStartPos); } Vector3 reflectionPos = reflection.MultiplyPoint(reflectionStartPos); Matrix4x4 worldToCameraMatrix = sourceCamera.worldToCameraMatrix; if (sourceCamera.stereoEnabled && eye == StereoTargetEyeMask.Left) { worldToCameraMatrix[12] += (sourceCamera.stereoSeparation * 0.5f); reflectionCamera.projectionMatrix = sourceCamera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Left); } else if (sourceCamera.stereoEnabled && eye == StereoTargetEyeMask.Right) { worldToCameraMatrix[12] -= (sourceCamera.stereoSeparation * 0.5f); reflectionCamera.projectionMatrix = sourceCamera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Right); } else { reflectionCamera.projectionMatrix = sourceCamera.projectionMatrix; } reflectionCamera.worldToCameraMatrix = worldToCameraMatrix * reflection; if (ClipPlaneOffset > 0.0f) { // Optimization: Setup oblique projection matrix so that near plane is our reflection plane. // This way we clip everything below/above it for free. Vector4 clipPlane = CameraSpacePlane(reflectionCamera, pos, reflectionNormal, ClipPlaneOffset, GL.invertCulling ? -1.0f : 1.0f); reflectionCamera.projectionMatrix = reflectionCamera.CalculateObliqueMatrix(clipPlane); } GL.invertCulling = !GL.invertCulling; reflectionCamera.transform.position = reflectionPos; // set the eye mask so that any command buffers know how to render this camera reflectionCamera.stereoTargetEye = eye; reflectionCamera.targetTexture = targetTexture; if (WeatherMakerCommandBufferManagerScript.Instance != null) { WeatherMakerCommandBufferManagerScript.Instance.RenderCamera(reflectionCamera); } reflectionCamera.targetTexture = null; reflectionCamera.transform.position = origReflectionStartPos; GL.invertCulling = oldInvertCulling; }
public static void TakeStereoScreenshot(uint screenshotHandle, GameObject target, int cellSize, float ipd, ref string previewFilename, ref string VRFilename) { const int width = 4096; const int height = width / 2; const int halfHeight = height / 2; Texture2D texture = new Texture2D(width, height * 2, TextureFormat.ARGB32, false); System.Diagnostics.Stopwatch timer = new System.Diagnostics.Stopwatch(); Camera tempCamera = null; timer.Start(); Camera camera = target.GetComponent <Camera>(); if (camera == null) { if (tempCamera == null) { tempCamera = new GameObject().AddComponent <Camera>(); } camera = tempCamera; } // Render preview texture const int previewWidth = 2048; const int previewHeight = 2048; Texture2D previewTexture = new Texture2D(previewWidth, previewHeight, TextureFormat.ARGB32, false); RenderTexture targetPreviewTexture = new RenderTexture(previewWidth, previewHeight, 24); RenderTexture oldTargetTexture = camera.targetTexture; bool oldOrthographic = camera.orthographic; float oldFieldOfView = camera.fieldOfView; float oldAspect = camera.aspect; StereoTargetEyeMask oldstereoTargetEye = camera.stereoTargetEye; camera.stereoTargetEye = StereoTargetEyeMask.None; camera.fieldOfView = 60.0f; camera.orthographic = false; camera.targetTexture = targetPreviewTexture; camera.aspect = 1.0f; camera.Render(); // copy preview texture RenderTexture.active = targetPreviewTexture; previewTexture.ReadPixels(new Rect(0, 0, targetPreviewTexture.width, targetPreviewTexture.height), 0, 0); RenderTexture.active = null; camera.targetTexture = null; Object.DestroyImmediate(targetPreviewTexture); SteamVR_SphericalProjection fx = camera.gameObject.AddComponent <SteamVR_SphericalProjection>(); Vector3 oldPosition = target.transform.localPosition; Quaternion oldRotation = target.transform.localRotation; Vector3 basePosition = target.transform.position; Quaternion baseRotation = Quaternion.Euler(0, target.transform.rotation.eulerAngles.y, 0); Transform transform = camera.transform; int vTotal = halfHeight / cellSize; float dv = 90.0f / vTotal; // vertical degrees per segment float dvHalf = dv / 2.0f; RenderTexture targetTexture = new RenderTexture(cellSize, cellSize, 24); targetTexture.wrapMode = TextureWrapMode.Clamp; targetTexture.antiAliasing = 8; camera.fieldOfView = dv; camera.orthographic = false; camera.targetTexture = targetTexture; camera.aspect = oldAspect; camera.stereoTargetEye = StereoTargetEyeMask.None; // Render sections of a sphere using a rectilinear projection // and resample using a sphereical projection into a single panorama // texture per eye. We break into sections in order to keep the eye // separation similar around the sphere. Rendering alternates between // top and bottom sections, sweeping horizontally around the sphere, // alternating left and right eyes. for (int v = 0; v < vTotal; v++) { float pitch = 90.0f - (v * dv) - dvHalf; int uTotal = width / targetTexture.width; float du = 360.0f / uTotal; // horizontal degrees per segment float duHalf = du / 2.0f; int vTarget = v * halfHeight / vTotal; for (int i = 0; i < 2; i++) // top, bottom { if (i == 1) { pitch = -pitch; vTarget = height - vTarget - cellSize; } for (int u = 0; u < uTotal; u++) { float yaw = -180.0f + (u * du) + duHalf; int uTarget = u * width / uTotal; int vTargetOffset = 0; float xOffset = -ipd / 2 * Mathf.Cos(pitch * Mathf.Deg2Rad); for (int j = 0; j < 2; j++) // left, right { if (j == 1) { vTargetOffset = height; xOffset = -xOffset; } Vector3 offset = baseRotation * Quaternion.Euler(0, yaw, 0) * new Vector3(xOffset, 0, 0); transform.position = basePosition + offset; Quaternion direction = Quaternion.Euler(pitch, yaw, 0.0f); transform.rotation = baseRotation * direction; // vector pointing to center of this section Vector3 N = direction * Vector3.forward; // horizontal span of this section in degrees float phi0 = yaw - (du / 2); float phi1 = phi0 + du; // vertical span of this section in degrees float theta0 = pitch + (dv / 2); float theta1 = theta0 - dv; float midPhi = (phi0 + phi1) / 2; float baseTheta = Mathf.Abs(theta0) < Mathf.Abs(theta1) ? theta0 : theta1; // vectors pointing to corners of image closes to the equator Vector3 V00 = Quaternion.Euler(baseTheta, phi0, 0.0f) * Vector3.forward; Vector3 V01 = Quaternion.Euler(baseTheta, phi1, 0.0f) * Vector3.forward; // vectors pointing to top and bottom midsection of image Vector3 V0M = Quaternion.Euler(theta0, midPhi, 0.0f) * Vector3.forward; Vector3 V1M = Quaternion.Euler(theta1, midPhi, 0.0f) * Vector3.forward; // intersection points for each of the above Vector3 P00 = V00 / Vector3.Dot(V00, N); Vector3 P01 = V01 / Vector3.Dot(V01, N); Vector3 P0M = V0M / Vector3.Dot(V0M, N); Vector3 P1M = V1M / Vector3.Dot(V1M, N); // calculate basis vectors for plane Vector3 P00_P01 = P01 - P00; Vector3 P0M_P1M = P1M - P0M; float uMag = P00_P01.magnitude; float vMag = P0M_P1M.magnitude; float uScale = 1.0f / uMag; float vScale = 1.0f / vMag; Vector3 uAxis = P00_P01 * uScale; Vector3 vAxis = P0M_P1M * vScale; // update material constant buffer fx.Set(N, phi0, phi1, theta0, theta1, uAxis, P00, uScale, vAxis, P0M, vScale); camera.aspect = uMag / vMag; camera.Render(); RenderTexture.active = targetTexture; texture.ReadPixels(new Rect(0, 0, targetTexture.width, targetTexture.height), uTarget, vTarget + vTargetOffset); RenderTexture.active = null; } // Update progress float progress = (float)(v * (uTotal * 2.0f) + u + i * uTotal) / (float)(vTotal * (uTotal * 2.0f)); OpenVR.Screenshots.UpdateScreenshotProgress(screenshotHandle, progress); } } } // 100% flush OpenVR.Screenshots.UpdateScreenshotProgress(screenshotHandle, 1.0f); // Save textures to disk. // Add extensions previewFilename += ".png"; VRFilename += ".png"; // Preview previewTexture.Apply(); System.IO.File.WriteAllBytes(previewFilename, previewTexture.EncodeToPNG()); // VR texture.Apply(); System.IO.File.WriteAllBytes(VRFilename, texture.EncodeToPNG()); // Cleanup. if (camera != tempCamera) { camera.targetTexture = oldTargetTexture; camera.orthographic = oldOrthographic; camera.fieldOfView = oldFieldOfView; camera.aspect = oldAspect; camera.stereoTargetEye = oldstereoTargetEye; target.transform.localPosition = oldPosition; target.transform.localRotation = oldRotation; } else { tempCamera.targetTexture = null; } Object.DestroyImmediate(targetTexture); Object.DestroyImmediate(fx); timer.Stop(); Debug.Log(string.Format("<b>[SteamVR]</b> Screenshot took {0} seconds.", timer.Elapsed)); if (tempCamera != null) { Object.DestroyImmediate(tempCamera.gameObject); } Object.DestroyImmediate(previewTexture); Object.DestroyImmediate(texture); }
void OnPreRender() //void OnRenderObject() { StereoTargetEyeMask currentEye = cam.stereoTargetEye; Matrix4x4 camPose = cam.worldToCameraMatrix; Matrix4x4 parentPose = transform.parent.worldToLocalMatrix; Matrix4x4 viewOffset = new Matrix4x4(); Vector3 eyePos = new Vector3(); Quaternion eyeRot = new Quaternion(); UbiMeasurementUtils.coordsysemChange(eyeOffset.transform.localPosition, ref eyePos); UbiMeasurementUtils.coordsysemChange(eyeOffset.transform.localRotation, ref eyeRot); //viewOffset.SetTRS(eyePos, eyeRot, new Vector3(1, 1, -1)); //viewOffset.SetTRS(eyeOffset.transform.localPosition, eyeOffset.transform.localRotation, new Vector3(1, 1, -1)); viewOffset.SetTRS(Vector3.zero, Quaternion.identity, new Vector3(1, 1, -1)); if (DisableOpenVRTracking) { transform.localPosition = Vector3.zero; transform.localRotation = Quaternion.identity; } Matrix4x4 viewMatrix = new Matrix4x4(); viewMatrix = viewOffset * eyeOffset.worldToLocalMatrix; //viewMatrix = viewMatrix.inverse; //Matrix4x4 newProjectionMatrix = Eye.projectionMatrix * viewOffset; Matrix4x4 newProjectionMatrix = Eye.projectionMatrix; Matrix4x4 parentMatrix = transform.parent.worldToLocalMatrix; // Debug.Log (name + " : "+ cam.GetStereoViewMatrix (Camera.StereoscopicEye.Left).ToString ("0.0000")); cam.projectionMatrix = newProjectionMatrix; //cam.projectionMatrix = Eye.projectionMatrix; transform.localPosition = eyeOffset.transform.localPosition; transform.localRotation = eyeOffset.transform.localRotation; if (CameraImage == null) { CameraImage = CameraTexture.getImageTexture(); } ARMaterial.SetTexture(ARMaterialTexName, CameraImage); switch (currentEye) { case StereoTargetEyeMask.None: case StereoTargetEyeMask.Both: case StereoTargetEyeMask.Left: //cam.SetStereoProjectionMatrix(Camera.StereoscopicEye.Left, newProjectionMatrix); //cam.SetStereoViewMatrix(Camera.StereoscopicEye.Left, viewOffset); //Matrix4x4 viewLeft = new Matrix4x4(); //viewLeft.SetTRS(Eye.transform.localPosition, Eye.transform.localRotation, Vector3.one); cam.SetStereoViewMatrix(Camera.StereoscopicEye.Left, viewMatrix); break; case StereoTargetEyeMask.Right: //cam.SetStereoProjectionMatrix(Camera.StereoscopicEye.Right, newProjectionMatrix); cam.SetStereoViewMatrix(Camera.StereoscopicEye.Right, viewMatrix); break; } }
private void AddRenderTextureForSourceCamera(Camera sourceCamera, RenderTexture tex, StereoTargetEyeMask eyeMask) { List <KeyValuePair <RenderTexture, StereoTargetEyeMask> > tmp; if (!sourceCamerasToRenderTextures.TryGetValue(sourceCamera, out tmp)) { sourceCamerasToRenderTextures[sourceCamera] = tmp = new List <KeyValuePair <RenderTexture, StereoTargetEyeMask> >(); } tmp.Add(new KeyValuePair <RenderTexture, StereoTargetEyeMask>(tex, eyeMask)); }
/// <summary> /// Render a reflection camera. Reflection camera should already be setup with a render texture. /// </summary> /// <param name="info">Camera info</param> /// <param name="reflectionTransform">Reflection transform</param> /// <param name="reflectionNormal">Reflection normal vector</param> /// <param name="clipPlaneOffset">Clip plane offset for near clipping</param> /// <param name="eye">Stereo eye mask</param> /// <param name="targetTexture">Target texture</param> private static void RenderReflectionInternal ( ReflectionCameraInfo info, Transform reflectionTransform, Vector3 reflectionNormal, float clipPlaneOffset, StereoTargetEyeMask eye, RenderTexture targetTexture ) { bool oldInvertCulling = GL.invertCulling; // find out the reflection plane: position and normal in world space Vector3 pos = reflectionTransform.position; // Render reflection // Reflect camera around reflection plane if (info.SourceCameraIsReflection && GL.invertCulling) { reflectionNormal = -reflectionNormal; } float d = -Vector3.Dot(reflectionNormal, pos) - clipPlaneOffset; Vector4 reflectionPlane = new Vector4(reflectionNormal.x, reflectionNormal.y, reflectionNormal.z, d); Matrix4x4 reflection; CalculateReflectionMatrix(out reflection, reflectionPlane); Vector3 savedPos = info.SourceCamera.transform.position; Vector3 reflectPos = reflection.MultiplyPoint(savedPos); Matrix4x4 worldToCameraMatrix = info.SourceCamera.worldToCameraMatrix; if (eye == StereoTargetEyeMask.Left) { worldToCameraMatrix[12] += (info.SourceCamera.stereoSeparation * 0.5f); info.ReflectionCamera.projectionMatrix = info.SourceCamera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Left); } else if (eye == StereoTargetEyeMask.Right) { worldToCameraMatrix[12] -= (info.SourceCamera.stereoSeparation * 0.5f); info.ReflectionCamera.projectionMatrix = info.SourceCamera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Right); } else { info.ReflectionCamera.projectionMatrix = info.SourceCamera.projectionMatrix; } info.ReflectionCamera.worldToCameraMatrix = worldToCameraMatrix * reflection; if (info.ReflectionCamera.actualRenderingPath != RenderingPath.DeferredShading) { // Optimization: Setup oblique projection matrix so that near plane is our reflection plane. // This way we clip everything below/above it for free. Vector4 clipPlane = CameraSpacePlane(info.ReflectionCamera, pos, reflectionNormal, clipPlaneOffset, GL.invertCulling ? -1.0f : 1.0f); info.ReflectionCamera.projectionMatrix = info.ReflectionCamera.CalculateObliqueMatrix(clipPlane); } GL.invertCulling = !GL.invertCulling; info.ReflectionCamera.transform.position = reflectPos; if (++renderCount < maxRenderCount) { info.ReflectionCamera.targetTexture = targetTexture; info.ReflectionCamera.Render(); info.ReflectionCamera.targetTexture = null; } info.ReflectionCamera.transform.position = savedPos; GL.invertCulling = oldInvertCulling; }