Having GUI elements in front of *everything* ?

Hi,

Is there a simple way in the new UI to make sure a screen space canvas is always rendered in front without using additional cameras?
This is important when dealing with a HUD-like UI for Rift-enabled games where you want to rely on the Rift cameras for rendering the screen space UI as well.
With NGUI we would customise the shader used, but I am not sure if that is possible with uGUI or if there is a parameter or sorting mode that can be set?

Thanks in advance!

It’s possible to assign a custom material to a UI.Graphic, and that custom material can have a shader that does what you want.

However in your situation I’d probably just use World Space Canvas as a child of the OVRController, and then add extra cameras to each eye position to clear depth and render it, and hack/change whatever’s needed in the OVR kit to make it render those extra camera prior to doing all the lens distortion processing.

1 Like

Thank! Well, we want to avoid extra cameras among other things to be able to avoid modifying the Oculus code too much since it is still very much a moving target. I had hoped the new GUI would have some way of forcing it to always draw on top since I can imagine other situations it might be useful besides VR…

It’s trivial to have the GUI always draw on top for a single camera - you just put the Canvas in Overlay mode - but I think it won’t be so easy for Rift projects because you need it to draw for two cameras.

With NGUI this was trivial as all GUI elements were regular geometry. According to the cross post on the QA thread, sorting layers might help but I need to read up on them in the docs and how a screen space canvas is rendered by multiple cameras (do a canvas bind to a certain camera?). Too ignorant at the moment. :slight_smile:

You can use multiple canvas with the new UI.
Each canvas has a sorting layer and a layer order.

You can also set your front GUI at the bottom of the canvas hierarchy

Sure, but is one canvas visible to all cameras? Ie. if you have a world space canvas, will both the OR cameras render that canvas? If so, the only thing needed is to make sure that canvas is rendered above everything - which might be possible with sorting (according to Unity in the QA thread, have to read the docs on it though).

Canvas have 3 Render Modes :

  • Screen space - Overlay : No need of any camera to render the Canvas. Child elements of the Canvas are render on top of all other Camera rendering.

  • Screen space - Camera : You have to set a rendering Camera. This camera’s Culling Mask must contain the canvas layer (in general named UI). Only this camera can render the canvas, even if you set UI in the culling mask of an other Camera.

  • World space : You have to set a rendering Camera. This camera’s Culling Mask must contain the canvas layer (in general named UI). One of the difference with Screen space - camera is that each Camera that contain Canva’s layer render this canvas. But the events (click, drag, etc…) are captured from the Camera set in the Canvas Event Camera.

if you want to be sure that your GUI is rendered on top of all other render, three options :

  • Set Screen space Overlay in the canvas
  • or change the Depth property of the camera rendering your UI. You can composite your final image on screen with multiple camera rendering differents parts of your scene (with specific cullin mask) and by playing with the depth property.
  • or play with Sorting Layer / Order in layer of canvas.

I’m using Unity 4.6 beta since two months, new UI is a real great tool.
I hope my explanations are clear and my english not too approximative.

#geff

2 Likes

Thanks for your reply, but I was well aware of those options.

The problem is that they are not good enough. With NGUI the solution was very simple: use another shader for the UI elements. Like I stated earlier: I am looking for a similar solution here, one that allows for world space UI elements that render in front of all objects - without additional cameras.
If it is not currently possible, I hope Unity will recognise the need for shader customisation. Having 2 extra cameras for a VR UI solution is not a practical or elegant solution.

Nope. The custom shader tags seems to be ignored. Pulling the same trick as we did with NGUI (forcing render in the overlay queue) has no effect. I frankly think it is a bit embarrassing that it is impossible to get a good answer re. this question from Unity. Frustrating.

The shader was not ignored, but the Z-testing was done in a special mode for the GUI. Switching to ztest always solved the issue. So, render queue overlay + ztest always does indeed work on GUI objects with a custom shader. That is the way to go if you need a HUD-like overlay drawn at comfortable distance for use with Rift/VR without adding two additional UI cameras.

Thanks to those who provided suggestions along the way.

1 Like

Hi Foxxis,

So the way I would recommend setting up a UI for this would be:

  • World space UI, both cameras set to render the UI.
  • The canvas parented to the cameras in a way that it moves with them nicely
  • Use RenderLayers to have the canvas render after everything else in the scene
  • Custom shader to change the ztest mode (It probably makes sense for us to expose the z-test option on the canvas itself… it would have default (unity decides), then the standard options… then no custom shader would be required.

If you are going to be using pointer (mouse ect, eye tracking) input then you will need to probably write a custom input module to do correct handling this also as right now it’s designed to work with a singular camera.

1 Like

Thanks Tim!
We actually got away with using raycasting from one camera POV with NGUI. It felt accurate enough in the rift. We’ll see how things work out with uGUI. However, implementing custom input modules looks easy, so that should not be a problem. Kudos for the open sourcing you are doing!

Yes, it would be very helpful to have the ability to say “I want this UI element to be shown but completely ignored otherwise.”. I’m running into issues where, if I have a tooltip that pops up over a button and it slightly overlaps, if the mouse is in the overlap, every time the tooltip obscures the button at that small spot it will make the button lose its “mouse is over you” status and the tooltip disappears, and so it starts strobing.

[quote=“JAKJ, post:15, topic: 547792, username:JAKJ”]
Yes, it would be very helpful to have the ability to say “I want this UI element to be shown but completely ignored otherwise.”. I’m running into issues where, if I have a tooltip that pops up over a button and it slightly overlaps, if the mouse is in the overlap, every time the tooltip obscures the button at that small spot it will make the button lose its “mouse is over you” status and the tooltip disappears, and so it starts strobing.
[/quote]Your tooltip object just needs a component with ICanvasRaycastFilter implemented on it, set up to return false from IsRaycastLocationValid. That’ll cause it to be ignored when raycasting, such that the mouse will never be ‘over’ it.

Or add a canvas group and turn off ‘blocks raycasts’

Y’know, that’s what’s so glorious about Unity: It’s like a giant box of legos and you put them together however best suits.

1 Like

Any idea if this is ever going to be implemented?

I’d rather them not be implementing new features at this point, because every new feature comes with new bugs. 4.6 needs to occur at some point.

1 Like