Skip to content
This repository has been archived by the owner on Nov 8, 2019. It is now read-only.

How to target different contents for each eye? #263

Closed
xdf103 opened this issue Jul 13, 2016 · 22 comments
Closed

How to target different contents for each eye? #263

xdf103 opened this issue Jul 13, 2016 · 22 comments

Comments

@xdf103
Copy link

xdf103 commented Jul 13, 2016

With v0.8.5, GvrEye now becomes Legacy. How can we target different contents for different eye? One usage for this is playbacking 3D videos. The video for left eye will be slight different from the right eye.

@miraleung
Copy link
Contributor

In the native Unity integration, a camera will be able to target a particular eye. In this case, your scene would have one camera per eye, and you would use layer masks to tweak the content that is sent.

@xdf103
Copy link
Author

xdf103 commented Jul 13, 2016

How is native Unity integration different from GVR Unity SDK? Where can I find more information about native Unity integration? If we use native Unity integration, can we still make use of some of the GVR features like spatial audio? Sorry for asking so many questions as I don't know what is native Unity integration.

@miraleung
Copy link
Contributor

These are great questions. The SDK is the "API" for GVR and Daydream development in Unity, and all GVR features will remain as we migrate to the editor with native integration.

If you look in our SDK, you'll notice that we include a native GVR library. Native integration means that Unity will call that from the editor, instead of us having to call it from the SDK level (as we currently do). This results in low-level and rendering optimizations that will make your app more performant.

Hope that helps!

@nathanmartz
Copy link

The native integration for Daydream is very similar to what exists today
for GearVR. It'll be available later this summer (dates TBD). We'll provide
more documentation when that comes out, but basically you'll get the same
feature set as you have today, but with better performance and lower
latency on Daydream Ready phones. Check out our Google IO VR talks if you
want more info.

On Wed, Jul 13, 2016 at 6:15 PM, Mira Leung notifications@github.com
wrote:

These are great questions. The SDK is the "API" for GVR and Daydream
development in Unity, and all GVR features will remain as we migrate to the
editor with native integration.

If you look in our SDK, you'll notice that we include a native GVR
library. Native integration means that Unity will call that from the
editor, instead of us having to call it from the SDK level (as we currently
do). This results in low-level and rendering optimizations that will make
your app more performant.

Hope that helps!


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#263 (comment),
or mute the thread
https://github.com/notifications/unsubscribe/ANamflWAPbht-GgKmA2WMXJoG6BnPzyfks5qVY2cgaJpZM4JLBAk
.

@jhclaura
Copy link

Thanks for the explanation @miraleung! Does it mean for now, before the fully integration, if we want to render different contents to different eyes, we should update the auto-generated Main Camera Left and Main Camera Right's Toggle Culling Mask with specific layers through scripts? If so, should it happen in Awake() or Start()?
Any advise and thoughts will be appreciated. Thanks!

@jhclaura
Copy link

jhclaura commented Aug 29, 2016

In the end, I accessed the Main Camera Left and Main Camera Right in Update() and update the culling masks manually. Looks hacky but works, below are the codes and hope it helps someone who has same needs.

`
using UnityEngine;
using System.Collections;

public class CamLayerManager : MonoBehaviour {

Transform leftEye;
Transform rightEye;
GvrEye leftEyeScript;
GvrEye rightEyeScript;
Camera leftEyeCam;
Camera rightEyeCam;
bool foundLeftEye = false;
bool foundRightEye = false;

public LayerMask rightEyeMask;
public LayerMask leftEyeMask;

void Start () {
    leftEye = transform.FindChild ("Main Camera Left");
    rightEye = transform.FindChild ("Main Camera Rigth");
}

void Update() {
    // LEFT
    if (!foundLeftEye) {
        leftEye = transform.FindChild ("Main Camera Left");

        if (leftEye == null) {
            Debug.LogWarning ("could not find leftEye");
        } else {
            Debug.Log("found leftEye!");
            //
            leftEyeScript = leftEye.gameObject.GetComponent<GvrEye>();
            leftEyeScript.toggleCullingMask = leftEyeMask;

            leftEyeCam = leftEye.gameObject.GetComponent<Camera>();
            leftEyeCam.cullingMask = leftEyeMask;
            //
            foundLeftEye = true;
        }
    }

    // RIGHT
    if (!foundRightEye) {
        rightEye = transform.FindChild ("Main Camera Right");

        if (rightEye == null) {
            Debug.LogWarning ("could not find rightEye");
        } else {
            Debug.Log("found rightEye!");
            //
            rightEyeScript = rightEye.gameObject.GetComponent<GvrEye>();
            rightEyeScript.toggleCullingMask = rightEyeMask;

            rightEyeCam = rightEye.gameObject.GetComponent<Camera>();
            rightEyeCam.cullingMask = ~rightEyeMask;
            //
            foundRightEye = true;
        }
    }
}

}
`

@steffkelsey
Copy link

steffkelsey commented Sep 21, 2016

Here's a nicer way to do it without all the magic Strings.
`using System.Collections;
using UnityEngine;

public class EyeLayerCull : MonoBehaviour
{
public LayerMask LeftEyeMask;
public LayerMask RightEyeMask;

void Start()
{
    StartCoroutine(LateStart());
}

protected IEnumerator LateStart()
{
    yield return new WaitWhile(() => GvrViewer.Controller == null);
    yield return new WaitWhile(() => GvrViewer.Controller.Eyes.Length < 2);
    foreach (GvrEye gvrEye in GvrViewer.Controller.Eyes)
    {
        switch (gvrEye.eye)
        {
            case GvrViewer.Eye.Left:
                gvrEye.toggleCullingMask = LeftEyeMask;
                break;
            case GvrViewer.Eye.Right:
                gvrEye.toggleCullingMask = RightEyeMask;
                break;
        }
    }
    GvrViewer.Controller.UpdateStereoValues();
}

}`

@jhclaura
Copy link

Indeed! Thanks for sharing!

@FrogsInSpace
Copy link

To make steffkelsey's code have an effect, you have to call GvrViewer.Controller.UpdateStereoValues(), otherwise the culling masks are not respected. So adding this line right before exiting the coroutine does fix this ...

@steffkelsey
Copy link

Thanks FrogsInSpace! I updated the code snippet adding in that change.

@oosmoxiecode
Copy link

oosmoxiecode commented Dec 12, 2016

Is this supposed to work for Daydream as well?

I am trying to use the script above in "Unity Daydream Preview 5.4.2f2-GVR12 (64-bit)" to do per eye culling. It works in the editor when testing, using the emulation.
But as soon as I try to build, it complains about GvrViewer.Controller.UpdateStereoValues(); as it then does not exist in that context.

So how do you do this for Daydream?

@steffkelsey
Copy link

Good question! I don't have time to try it atm. I am not sure how much the Daydream stuff differs from Cardboard. You would think they would be the same? If I get a chance to try it this week i'll let you know.

@oosmoxiecode
Copy link

Hi, thanks for the reply! :)

I fiddled a few hours with this yesterday, turns out it does differ from the cardboard and how the "emulation" in unity works. Which I found was quite confusing..

For future reference if anyone finds this thread, the solution for Daydream was to make 2 cameras(one left, one right), put them inside the GvrViewer and set the "Target Eye" for each one to Left/Right. And then set up the Culling Mask for each camera.

But you won´t see it working correctly inside Unity(using the emulation), but you will see it working on the Phone/Daydream.

@ibrews
Copy link

ibrews commented Feb 24, 2017

AHHH I'm so glad I found this. @oosmoxiecode , thanks so much for your explanation-- I've been struggling with how to do this on daydream for a while now. Finally it's working!

And just to further clarify, for anyone who is now finding this and trying to do the same thing, these are the steps: (mind you I'm using Unity 5.4.2 GVR-13 so maybe it's different in 5.6):

  1. Have a scene with standard non-camera stuff for Daydream already setup (like GvrViewerMain and GvrControllerMain and whatnot)
  2. Create an empty game object and attach the Gvr Head component to it.
  3. Uncheck Track Rotation and Track Position
  4. Inside that game object, create two basic unity cameras (put them both at 0,0,0 inside the parent)
  5. Treat one camera as the left eye and one as the right eye. In the camera Target Eye settings, choose Left for one and Right for the other.
  6. Then uncheck whatever layers in the Culling Masks that each eye shouldn't see.

Ta-da! Yes indeed it does not look right in Unity but it does in Daydream!!

@eyalfx
Copy link

eyalfx commented Mar 14, 2017

I can't get this to work on 5.6.b11 .
I also can't find any camera when doing FindObjectsOfType() besides the one Main Camera.
So I'm not sure what is Unity doing behind the scene when running on device, but there are no other camera's in the scene to change the culling mask.
Anyone figured it out?
Thanks

@ibrews
Copy link

ibrews commented Mar 14, 2017

@eyalfx - instead of dong FindObjectsOfType, try building an array with GetComponentsInChildren< Camera >()

@eyalfx
Copy link

eyalfx commented Mar 14, 2017

Thanks ibrews. I tried that first and there were no cameras to be found under the main camera. Which is why I tried FindObjectsOfType to see if there are any other cameras in the scene (anywhere)... but there are none. really strange how there are no other cameras for stereo rendering.

@ibrews
Copy link

ibrews commented Mar 14, 2017

Maybe you're misunderstanding the solution being discussed in this thread. You need to add the left and right camera manually within Unity-- if you want this to work you can't let google do it's automatic camera adding to the main camera like it normally would.

@eyalfx
Copy link

eyalfx commented Mar 14, 2017

I know this worked for you on 5.4, but did you happen to try it on 5.6 ?
I did try to add the cameras manually following the instructions , but it didn't quite work.

@ibrews
Copy link

ibrews commented Mar 14, 2017

gotcha. no I haven't tried this on 5.6 yet.

@cjsauer
Copy link

cjsauer commented Mar 23, 2017

For people trying to play 360 stereoscopic video in Cardboard, I got this working in Unity 5.6 over at issue #511

@havergooday
Copy link

havergooday commented May 15, 2017

#570
is it work in Android?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests