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?
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.
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.
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).
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.
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.
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.
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.