public void SetOdsRendererType(OdsRendererType type) { //Currently StereoCubemap ODS rendering is only supported in the editor or when experimental is //enabled. If/When StereoCubemap ODS rendering is fully supported, removed this #if/#else/#endif. #if (UNITY_EDITOR || EXPERIMENTAL_ENABLED) if (!isExperimental()) { type = OdsRendererType.StereoCubemap; } #else type = OdsRendererType.StereoCubemap; #endif if (type != rendererType) { Debug.Assert(type < OdsRendererType.Count); if (odsRenderer != null) { odsRenderer.Release(); } if (type == OdsRendererType.Slice) { Debug.Log("ODS Mode: Slice"); odsRenderer = new OdsSlice(); } else { Debug.Log("ODS Mode: Stereo Cubemap"); odsRenderer = new OdsStereoCubemap(); } odsRenderer.SetVr180(vr180); } rendererType = type; }
public void Awake() { CollapseIpd = true; odsRenderer = new OdsSlice(); odsRenderer.SetVr180(vr180); rendererType = OdsRendererType.Slice; lastRendererType = rendererType; Debug.Log("Init ODS Mode: " + rendererType.ToString()); if (outputFolder == null) { outputFolder = System.Environment.GetFolderPath( System.Environment.SpecialFolder.DesktopDirectory) + "/ODS"; } }
public IEnumerator Render(Transform node) { if (imageWidth != lastImageWidth || bloomRadius != lastBloomRadius || lastRendererType != rendererType || lastvr180 != vr180) { // Round image width to a mutiple of four to keep symmetry with the image height. imageWidth = Math.Min(((imageWidth + 3) / 4) * 4, MaxImageWidth); SetupTextures(); lastImageWidth = imageWidth; lastBloomRadius = bloomRadius; lastRendererType = rendererType; lastvr180 = vr180; } if (outputFolder != null && !Directory.Exists(outputFolder)) { Directory.CreateDirectory(outputFolder); } GameObject renderCameraObject = new GameObject(); renderCameraObject.transform.parent = node.transform; Camera renderCamera = renderCameraObject.AddComponent <Camera>() as Camera; Camera parentCamera = GetComponent <Camera>(); if (Camera.main == null) // this may occur if the camera is disabled { parentCamera = GetComponent <Camera>(); Debug.Assert(parentCamera != null); } renderCamera.CopyFrom(parentCamera); renderCamera.cullingMask = parentCamera.cullingMask; renderCamera.name = "Hybrid ODS Camera"; renderCamera.fieldOfView = 90.0f; if (opaqueBackground) { // TBD - Specify full alpha for exported image Color background = parentCamera.backgroundColor; background.a = 1.0f; renderCamera.backgroundColor = background; } ParticleSystemRenderer[] renderers = FindObjectsOfType <ParticleSystemRenderer>(); for (int i = 0; i < renderers.Length; ++i) { renderers[i].maxParticleSize *= particleScaleFactor; } // Remove pitch/elevation and roll/bank, but preserve yaw/heading. Quaternion origRotation = node.rotation; renderCamera.rect = new Rect(0, 0, 1.0f, 1.0f); renderCamera.transform.localRotation = Quaternion.Euler(0.0f, 0.0f, 0.0f); renderCamera.transform.localPosition = new Vector3(0.0f, 0.0f, 0.0f); float scale = renderCamera.transform.lossyScale.x; renderCamera.nearClipPlane = parentCamera.nearClipPlane * scale; renderCamera.farClipPlane = parentCamera.farClipPlane * scale; #if ENABLE_TIMING timerStart(); #endif isRendering = true; //This suspends the execution of this function while running the odsRenderer.Render() function //as a coroutine and will then resume execution when it is done. yield return(StartCoroutine( odsRenderer.Render(renderCamera, node, stitched, interPupillaryDistance * scale, CollapseIpd, MaxRenders) )); isRendering = false; #if ENABLE_TIMING double deltaMs = timerStop(); print("OdsRender - Render time: " + deltaMs.ToString() + "ms"); #endif node.rotation = origRotation; Destroy(renderCameraObject); for (int i = 0; i < renderers.Length; ++i) { renderers[i].maxParticleSize /= particleScaleFactor; } var oldActiveTexture = RenderTexture.active; RenderTexture.active = finalImage; GL.Clear(true, true, Color.black); RenderTexture.active = oldActiveTexture; bool useBloomedImage = false; MonoBehaviour[] behaviours = gameObject.GetComponents <MonoBehaviour>(); foreach (MonoBehaviour b in behaviours) { MethodInfo m = b.GetType().GetMethod("OnRenderImage"); if (m != null && m.IsPublic && b.enabled) { //Apply the bloom and composite. if (vr180) { SbsBloomAndComposite(stitched, finalImage, b, m); } else { StackedBloomAndComposite(stitched, finalImage, b, m); } useBloomedImage = true; break; } } //When bloom is not enabled, we still have to composite. if (!useBloomedImage) { if (vr180) { SbsComposite(stitched, finalImage); } else { StackedComposite(stitched, finalImage); } } oldActiveTexture = RenderTexture.active; RenderTexture.active = finalImage; returnImage.ReadPixels(new Rect(0, 0, finalImage.width, finalImage.height), 0, 0); RenderTexture.active = oldActiveTexture; Graphics.Blit(finalImage, (RenderTexture)null); byte[] image = returnImage.EncodeToPNG(); string file = String.Format(basename + "_{0:d6}.png", frameCount); string path = Path.Combine(outputFolder, file); #if MULTI_THREADED Thread imageWriter = new Thread(() => { File.WriteAllBytes(path, image); #if LOG_IMAGE_WRITES Debug.Log("Wrote image " + path); #endif }); imageWriter.IsBackground = true; imageWriter.Start(); #else File.WriteAllBytes(path, image); #if LOG_IMAGE_WRITES Debug.Log("Wrote image " + path); #endif #endif frameCount++; } // Render method