cancel
Showing results for 
Search instead for 
Did you mean: 

Unity 5 Bug: Left Eye renders incorrectly on device

rjmig88
Honored Guest
Update:
Making the OVRCameraRig a top level object fixes this left eye rendering issue for me. It seems to occur if you make it a child of another game object and move that object around on device on android.

Original Issue:

System Info:
Unity 5.0.0p2
Mobile SDK 0.4.3.1
Exynos Gear VR Android 5.0.1 Lollipop
Android ETC2 (OpenGL ES 3.0) forced. Using default Mobile SDK Project Settings.

On device only the left eye is rendering incorrect light values/etc in complex scenes involving multiple shaders. I haven't quite figured out what is going on yet. Here is an example picture from the Top Down Assets (https://www.assetstore.unity3d.com/en/#!/content/5860) demo scene:
http://i.imgur.com/y3k7qd8.jpg

The left and right eye is rendering correctly both in editor(set to android platform) and on Windows build.

I'm not really sure where to begin to troubleshoot this issue. I've noticed on a simpler scene if I use the VRGUI class - viewtopic.php?f=37&t=4944 then it triggers the issue if I have mixed shaders (some objects using the bump diffuse shaders, others using the parallax diffuse shaders, etc.) It goes away if I use the same shader for everything. My best guess currently is anything relying on RenderTexture on device will trigger this issue.

Has anyone else ran across this issue? Has anyone else been able to resolve it?

Thanks!
24 REPLIES 24

rjmig88
Honored Guest
I saw Unity just released 5.0.0p3. I upgraded to it and the same issue still occurs.

stan4oculus
Honored Guest
Hi,

I do not know if this is related or not but we get left eye flickering a lot.
It is left eye only and on phone only.
We use 4.6.3 Unity and 4.4 android.
Flicker happens only if we've got forced Gles3.
Oculus camera is set to mono so exactly same picture is expected to be rendered but its not apparently.
Muti-threaded rendering is on. if it is off then both eyes flicker horribly.
With Gles 2 it seems to be ok.

Stan

rjmig88
Honored Guest
Hi Stan,

I've had left eye flickering as well. That went away with the Lollipop update so I'd highly encourage you to try that. The issue I'm reporting in this thread seems to be an issue with render textures, Unity 5, and the mobile SDK. I have a sample project I'm willing to share with Oculus and Unity if they're interested.

Cheers!

- Randy

rjmig88
Honored Guest
Just tried mobile SDK 0.5.0 on Unity 5.0.0p3. I also tried forcing OpenGL ES 2.0. I'm still having the same issues on device only. http://i.imgur.com/LbnjnJy.jpg

If I run this script (attached to the OVR camera rig or attached to the right/left eye anchor) then the left eye renders incorrectly for mixed shader content. If I don't run the UI then both eyes are fine.

using UnityEngine;
using System.Collections;


public class FpsCounter : VRGUI
{
// Attach this to a GUIText to make a frames/second indicator.
//
// It calculates frames/second over each updateInterval,
// so the display does not keep changing wildly.
//
// It is also fairly accurate at very low FPS counts (<10).
// We do this not by simply counting frames per interval, but
// by accumulating FPS for each frame. This way we end up with
// correct overall FPS even if the interval renders something like
// 5.5 frames.

public float updateInterval = 0.5F;

private float accum = 0; // FPS accumulated over the interval
private int frames = 0; // Frames drawn over the interval
private float timeleft; // Left time for current interval

private string fpsStr;

public override void OnVRGUI()
{
GUILayout.BeginArea(new Rect(Screen.width / 2.25f, Screen.height / 2.25f, Screen.width, Screen.height));
GUILayout.Label(fpsStr);
GUILayout.EndArea();
}


void Start()
{
timeleft = updateInterval;
}

void Update()
{
timeleft -= Time.deltaTime;
accum += Time.timeScale / Time.deltaTime;
++frames;

// Interval ended - update GUI text and start new interval
if (timeleft <= 0.0)
{
// display two fractional digits (f2 format)
float fps = accum / frames;
string format = System.String.Format("FPS: {0:F2}", fps);
fpsStr = format;

// DebugConsole.Log(format,level);
timeleft = updateInterval;
accum = 0.0F;
frames = 0;
}
}
}


And here is the code for VRGUI. It is really simple, it just creates a RenderTexture, draws the UI to that texture, then puts it in world space out in front of the camera.

using UnityEngine;
using System.Collections;
/// <summary>
/// Source code by boone188:
/// https://forums.oculus.com/viewtopic.php?f=37&t=4944
/// </summary>
public abstract class VRGUI : MonoBehaviour
{
public Vector3 guiPosition = new Vector3(0f, 0f, 1f);
public float guiSize = 1f;
public bool useCurvedSurface = true;
public bool acceptMouse = true;
public bool acceptKeyboard = true;
public int cursorSize = 32;
public Texture customCursor = null;

private GameObject guiRenderPlane = null;
private RenderTexture guiRenderTexture = null;
private Vector2 cursorPosition = Vector2.zero;
private Texture cursor = null;

private bool isInitialized = false;

private void Initialize ()
{
// create the render plane
if (useCurvedSurface)
{
guiRenderPlane = Instantiate(Resources.Load("VRGUICurvedSurface")) as GameObject;
}
else
{
guiRenderPlane = Instantiate(Resources.Load("VRGUIFlatSurface")) as GameObject;
}

// position the render plane
guiRenderPlane.transform.parent = this.transform;
guiRenderPlane.transform.localPosition = guiPosition;
guiRenderPlane.transform.localRotation = Quaternion.Euler(0f, 180f, 0f);
guiRenderPlane.transform.localScale = new Vector3(guiSize, guiSize, guiSize);

// create the render texture
guiRenderTexture = new RenderTexture(Screen.width, Screen.height, 24);

// assign the render texture to the render plane
guiRenderPlane.GetComponent<Renderer>().material.mainTexture = guiRenderTexture;

if (acceptMouse)
{
// create the cursor
if (customCursor != null)
{
cursor = customCursor;
}
else
{
cursor = Resources.Load("SimpleCursor") as Texture;
}
}

isInitialized = true;
}

protected void OnEnable()
{
if (guiRenderPlane != null)
{
guiRenderPlane.SetActive(true);
}
}

protected void OnDisable()
{
if (guiRenderPlane != null)
{
guiRenderPlane.SetActive(false);
}
}

protected void OnGUI()
{
if (!isInitialized)
{
Initialize();
}

// handle mouse events
if (Event.current.isMouse)
{
// return if not accepting mouse events
if (!acceptMouse)
{
return;
}
}
if (acceptMouse)
{
// save the mouse position
cursorPosition = new Vector2(Input.mousePosition.x, Screen.height - Input.mousePosition.y);
}

// handle key events
if (Event.current.isKey)
{
// return if not accepting key events
if (!acceptKeyboard)
{
return;
}
}

// save current render texture
RenderTexture tempRenderTexture = RenderTexture.active;

// set the render texture to render the GUI onto
if (Event.current.type == EventType.Repaint)
{
RenderTexture.active = guiRenderTexture;
GL.Clear (false, true, new Color (0.0f, 0.0f, 0.0f, 0.0f));
}

// draw the VRGUI
OnVRGUI();

if (Event.current.type == EventType.Repaint)
{
if (acceptMouse)
{
// draw the cursor
GUI.DrawTexture(new Rect(cursorPosition.x, cursorPosition.y, cursorSize, cursorSize),
cursor, ScaleMode.StretchToFill);
}

// restore the previous render texture
RenderTexture.active = tempRenderTexture;
}
}

public abstract void OnVRGUI();
}


Has anyone else been having issues? This is a major blocker for me in general and for the VR jam.

cybereality
Grand Champion
Can you provide me with a logcat from the device?
AMD Ryzen 7 1800X | MSI X370 Titanium | G.Skill 16GB DDR4 3200 | EVGA SuperNOVA 1000 | Corsair Hydro H110i Gigabyte RX Vega 64 x2 | Samsung 960 Evo M.2 500GB | Seagate FireCuda SSHD 2TB | Phanteks ENTHOO EVOLV

cybereality
Grand Champion
Also, can you share a sample project that shows the issue? I can have someone take a look.
AMD Ryzen 7 1800X | MSI X370 Titanium | G.Skill 16GB DDR4 3200 | EVGA SuperNOVA 1000 | Corsair Hydro H110i Gigabyte RX Vega 64 x2 | Samsung 960 Evo M.2 500GB | Seagate FireCuda SSHD 2TB | Phanteks ENTHOO EVOLV

rjmig88
Honored Guest
Thank you cybereality! I'll send you a PM with a link to my project and with instructions on how to trigger the rendering bugs. Another bug I found today I added some trees to the scene and somehow the tree texture on device got baked into the house texture, even removing the trees from the scene and rebaking it in unity. That doesn't happen either in the editor or on windows. The tree texture goes away if I enable the fps counter (left eye still busted), but otherwise remains on the "normal" run. The project I'm including has the trees as well as everything else.

Picture with tree texture incorrectly baked on the roof on device:
http://i.imgur.com/zpIjlRQ.jpg

I've uploaded the logs from both runs to this post.

IronMan
Honored Guest
I'm pretty sure in the mobile docs they say "don't use OnGUI()". If they don't, they should.

Besides being highly inefficient, time warp on android has a specific order in which all the rendering takes place.

Take a look at how OVRScreenFade works and try to use OnCustomPostRender to get your GUI code working. You may have to modify OVRPostRender to run and get added on PC. I don't remember what the current released state of that code is.

Generally, on mobile, anything you want to render on top of your scene (and work correctly in both eyes) you should use the OnCustomPostRender message.

rjmig88
Honored Guest
Thank you so much! I totally missed that part in the mobile documentation where it says Do not use Unity’s OnGUI() calls. Since it is labeled under CPU Optimizations my thoughts were that you just had to be careful since it may get called multiple times per frame. I didn't realize that it would result in graphical glitches due to rendering order.

I'll give your method a shot and report back.