Hi, recently, I noted that Unity does not provide the functionality for the side-by-side stereo rendering. Thus, in this tutorial, I want to show you how to implement a side-by-side stereo camera setup in Unity 2018. We are going to implement a small application with the camera setup, that will allow you to switch between the mono mode and side-by-side mode. To achieve that, we to do the following steps:
- First, create a new Unity application ( for that tutorial I used Unity 2018) and delete the Main Camera in the created scene.
- Create a new 3D object (for instance, a Cube) and set the position of its transform to (0,0,2) in the Inspector view.
- Now, add a new empty GameObject to the scene and call it CameraHead. Set its position and rotation to (0,0,0).
- Next, in the Inspector view of the CameraHead object, click on the Button Add Component, scroll down, and select the option New Script.
- Name the script CameraSetup and confirm by clicking on the Create and Add button.
- Double-click on the script to open it in the Visual Studio.
- Replace the content of the script file with the following code:
using UnityEngine; public class CameraSetup : MonoBehaviour { private Transform cameraHeadTransform; private GameObject monoCamera; private GameObject leftEyeCamera; private GameObject rightEyeCamera; public float EyeSeparation = 0.08f; public float NearClipPlane = 0.01f; public float FarClipPlane = 100.0f; public float FieldOfView = 60.0f; private bool isStereo; void Start() { // Get the transform of the CameraHead gameobject cameraHeadTransform = gameObject.transform; // create mono camera monoCamera = new GameObject("monoCamera"); monoCamera.transform.SetParent(cameraHeadTransform.transform); var camera = cameraHeadTransform.gameObject.AddComponent<Camera>(); camera.nearClipPlane = NearClipPlane; camera.farClipPlane = FarClipPlane; // create stereo camera setup leftEyeCamera = new GameObject("leftEyeCamera"); leftEyeCamera.transform.SetParent(cameraHeadTransform.transform); leftEyeCamera.transform.localPosition -= new Vector3(0.04f, 0, 0); var cameraLE = leftEyeCamera.AddComponent<Camera>(); cameraLE.rect = new Rect(0, 0, 0.5f, 1); cameraLE.fieldOfView = FieldOfView; cameraLE.aspect *= 2; cameraLE.nearClipPlane = NearClipPlane; cameraLE.farClipPlane = FarClipPlane; leftEyeCamera.SetActive(false); rightEyeCamera = new GameObject("rightEyeCamera"); rightEyeCamera.transform.SetParent(cameraHeadTransform.transform); rightEyeCamera.transform.localPosition += new Vector3(0.04f, 0, 0); var cameraRE = rightEyeCamera.AddComponent<Camera>(); cameraRE.rect = new Rect(0.5f, 0, 0.5f, 1); cameraRE.fieldOfView = FieldOfView; cameraRE.aspect *= 2; cameraRE.nearClipPlane = NearClipPlane; cameraRE.farClipPlane = FarClipPlane; rightEyeCamera.SetActive(false); isStereo = false; } void Update() { if (Input.GetKeyDown(KeyCode.Alpha1)) { isStereo = false; } else if (Input.GetKeyDown(KeyCode.Alpha2)) { isStereo = true; } monoCamera.SetActive(!isStereo); leftEyeCamera.SetActive(isStereo); rightEyeCamera.SetActive(isStereo); } }
The code is relatively simple. In the Start method, we create three cameras: mono, left eye, and right eye. The mono camera is a default camera with default parameters.
Much more interesting are the left eye and right eye cameras. We will use them for the side-by-side stereo mode rendering images for the left and right user’s eyes respectively. We set the distance along the X-axis between the left and right eye cameras equal to the value of the EyeSeparation variable (in the code it is eight cm). Thus, those cameras will render a slightly different view of the scene, creating a 3D effect.
Other important properties of the left and right eye cameras we have to set up are rect and aspect. The rect property defines the viewport area cameras will render to. So the left eye camera will render to the left half of the viewport ( cameraLE.rect = new Rect(0, 0, 0.5f, 1); ) and the right eye camera to the right part ( cameraRE.rect = new Rect(0.5f, 0, 0.5f, 1); ). Notice that the rect has to be defined in the normalized coordinates means in the range [0,1].
Finally, we have to adjust the aspect property of the cameras, but only if you use an LCD-based or LED-based display. If you use a Projector-based setup for a stereo output with two projectors, where each projector renders an image for one eye, then you do not have to manipulate the aspect property, Unity will set the proper value. LCD-based or LED-based displays, on the other hand, will stretch the renderings of individual cameras in the stereo mode, so they fill the entire screen. Thus, we have to narrow the aspects of the stereo cameras ( e.g., cameraLE.aspect *= 2; ) to have a proper aspect in the stereo mode.
In the Update method, we are listening to the user input and activate the mono mode if the user presses the 1 key or stereo mode if the user presses the 2 key.
You can download the code for this tutorial on GitHub: