unity-game-enginegoogle-vrstereoscopyphotosphere

Stereoscopic video setup not working in Unity


I'm trying to view (Top Bottom) stereoscopic video using a photosphere and the culling mask technique for GoogleVR (Daydream), but it doesn't seem to be working as intended. Here's what I've done:

Basically my scene has 2 cameras and 2 photospheres in exact same positions. I'm using the Culling Mask element of the left Camera to block the right Sphere and vice versa for the right Camera, so the left eye only sees the left sphere and the right eye, only the right sphere. The "LeftSphere" is playing the top half of the video and the "RightSphere" is playing the bottom half. Therefore, I should be seeing stereoscopic.

Also, since my scene is VR enabled, there is a "Target Eye" element on both cameras. I set that accordingly - Left for left camera and Right for right camera.

The problem is when I play my scene in Unity to test it, it's playing only the RightSphere on both eyes and the left sphere is not being seen by any camera.

Here's what I found out is going on. I just don't know how to fix it:

(I'm using UMP - UniversalMediaPlayer unity asset for video, btw)

I've tried it on my daydream viewer with my Pixel and it is indeed only playing monoscopic.

Child cameras appearing. Unable to edit them in "edit mode"


Solution

  • Alright, so I finally got it working! In case anyone is running into the same issue in the future, here's what you need to do:

    I'm using Unity 2017.1.0b4 and UniversalMediaPlayer for my video player. Note that this is only for GoogleVR.

    1. Enable VR in Player Settings
    2. Import GoogleVR asset into Unity
    3. Place "GvrViewerMain" prefab in your scene
    4. Duplicate Camera and reset both camera coords to zero. I named my cameras "LeftEye/RightEye"
    5. Create a Sphere and reset coords to zero as well, then duplicate. I named them "LeftSphere/RightSphere"
    6. Create two new Layers and name them "LeftSphere" and "RightSphere"
    7. On "LeftEye" camera Culling Mask element, uncheck "RightSphere". Uncheck "LeftSphere" on the "RightEye camera.
    8. Change the "Target Eye" element on each camera to correspond to the correct eye.
    9. Create 2 new materials, one for each sphere, then drag them on each sphere.
    10. Change the Shader for both spheres to "UMP/VideoSphericalCanvas" (You need UMP from asset store) Edit: Forgot to mention to import and setup your UMP prefab and drag both spheres to it. Super easy to setup, btw.
    11. On the "LeftSphere" change the Tiling to X1 - Y0.5 & Offset to X0 Y0
    12. On the "RightSphere" change the Tiling to X1 - Y0.5 & Offset to X0 Y0.5
    13. Change the Layer from "Default" to "LeftSphere" (layer you created earlier) on the LeftSphere, and vice versa for the right sphere.

    This is where it was causing me issues. Because new cameras are created every time you load or play your app, I had to find a way to change the "Culling Mask" and the "Target Eye" for these 4 cameras. The only way I found how to do that was through a script.

    1. Attach this script to your "LeftEye" and "RightEye" game objects and you'll have 2 new drop downs in your inspector for left and right eye masks. Change those accordingly (same as above culling masks).

    GameObject left;
    Camera leftEye;
    
    GameObject right;
    Camera rightEye;
    
    public LayerMask LeftEyeMask;
    public LayerMask RightEyeMask;
    
    // Use this for initialization
    void Start () {
        left = GameObject.Find(gameObject.name + " Left");
        if (left != null) leftEye = left.GetComponent<Camera>();
    
        right = GameObject.Find(gameObject.name + " Right");
        if (right != null) rightEye = right.GetComponent<Camera>();
    }
    
    // Update is called once per frame
    void Update () {
    
        // LEFT EYE
        if (left == null)
        {
            left = GameObject.Find(gameObject.name + " Left");
            if (left != null)
                leftEye = left.GetComponent<Camera>();
        }
        else
        {
            leftEye = left.GetComponent<Camera>();
            if (leftEye != null)
            {
                leftEye.stereoTargetEye = StereoTargetEyeMask.Left;
                leftEye.cullingMask = LeftEyeMask.value;
            }
        }
    
        // RIGHT EYE
        if (right == null)
        {
            right = GameObject.Find(gameObject.name + " Right");
            if (right != null)
                rightEye = right.GetComponent<Camera>();
        }
        else
        {
            rightEye = right.GetComponent<Camera>();
            if (rightEye != null)
            {
                rightEye.stereoTargetEye = StereoTargetEyeMask.Right;
                rightEye.cullingMask = RightEyeMask;
            }
        }
    }
    

    Your Top-Bottom video should now be playing in 3D in Daydream or Cardboard.