Search Unity

Simple white text on black background as UI in HMD

Discussion in 'AR/VR (XR) Discussion' started by bdeschryver, Oct 17, 2017.

  1. bdeschryver

    bdeschryver

    Joined:
    Jun 13, 2013
    Posts:
    93
    Hey,

    I am trying to display a simple white text in front of black background in my HTC Vive (and only that showing).
    I tried using a Screen space overlay canvas, but that shows only in the 2D view... (not in Vive itself).
    I know it is recommended to use world space for canvas, but here I only need to fade that canvas/Gui in to display a static text in the HMD, and then fade it out to the game scene when needed.
    Any way you would do it?
    Using World space will interfere with objects in my game environment, right ?

    Thanks for your help !

    Capture.JPG
     

    Attached Files:

  2. mcarney

    mcarney

    Joined:
    Jul 25, 2013
    Posts:
    7
    Do you want it to be attached to the HMD? If so, do you have it attached to the HMD / camera?

    World space just means that the text is relative to the world, as opposed to attached to your face.
     
  3. SiliconDroid

    SiliconDroid

    Joined:
    Feb 20, 2017
    Posts:
    302
    Hi,

    You can prevent this, here's what I would do:

    Spawn a large quad (single cell plane) with a TextMeshPro text on it, place it like 10m in fron of cam in world space and, child the quad to nothing, child the TextMeshPro to the quad.

    Now if you used standard materials then you will see any of your game geometry occlude this sign you've made. And if you do not have determinism over where your player may be this is a problem, the sign may never be seen if they are facing a wall etc.

    But... if you disable ztest and zwrite on the quad and mesh material and give them a high render queue priority they will be drawn over everything, regardless of Zpos relative to cam.

    To disable ztest/zwrite you need a shader setup for that.

    Here is a simple color shader for your quad:
    Code (CSharp):
    1. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    2. //   ____ ___ _     ___ ____ ___  _   _   ____  ____   ___ ___ ____
    3. //  / ___|_ _| |   |_ _/ ___/ _ \| \ | | |  _ \|  _ \ / _ \_ _|  _ \
    4. //  \___ \| || |    | | |  | | | |  \| | | | | | |_) | | | | || | | |
    5. //   ___) | || |___ | | |__| |_| | |\  | | |_| |  _ <| |_| | || |_| |
    6. //  |____/___|_____|___\____\___/|_| \_| |____/|_| \_\\___/___|____/
    7. //
    8. //    MOBILE: UNLIT COLOR WITH ALPHA
    9. //
    10. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    11.  
    12. Shader "SiliconDroid/Mobile_UnlitAlphaTextureNoZ"
    13. {
    14.     Properties
    15.     {
    16.         _Alpha ("Alpha", Range (0.0,1.0)) = 1.0
    17.         _MainTex ("Base (RGB) Transparency (A)", 2D) = "" { }
    18.     }
    19.  
    20.     Category
    21.     {
    22.         Lighting Off
    23.         ZWrite Off
    24.         ZTest Off
    25.         Cull back
    26.         Blend SrcAlpha OneMinusSrcAlpha
    27.         Tags {Queue=Transparent}
    28.         SubShader
    29.         {
    30.             Pass
    31.             {
    32.                 SetTexture [_MainTex]
    33.                 {
    34.                    constantColor (1, 1, 1, [_Alpha])
    35.                    combine texture * constant
    36.                 }
    37.             }
    38.         }
    39.     }
    40. }
    41.  
    42.  
    For the TextMeshPro, you can select one of it's bundled shaders to do the same, you might also use that shader instead of the one I supplied above for your quad.

    I recommend: spawn your big sign with both it materials at zero alpha and use a script to ramp the alpha to 1 over some time, this will have the result of fading your scene to this sign.

    Use this function to change your alphas in script:

    Code (CSharp):
    1. // modulate float fAlpha using coroutine etc.
    2. oMyMaterial.SetFloat("_Alpha", fAlpha);
     
    Last edited: Oct 24, 2017
  4. bdeschryver

    bdeschryver

    Joined:
    Jun 13, 2013
    Posts:
    93
    Thanks for that !
    Would you confirm that screen space overlay is definitely not possible with VR ? (and shown in the headset)
     
  5. bdeschryver

    bdeschryver

    Joined:
    Jun 13, 2013
    Posts:
    93
    I want it to be attached to the camera of the HMD. I mean, this welcome text should move with the HMD, so that the user sees it as a fixed text in the headset and does not (yet) feel any interaction or motion tracking. It is easy to achieve using a world space canvas but then objects that come between the camera and the canavs will show on HMD. One solution is using a specific shader which shows on top of all others, as SiliconDroid mentionned. I was just hoping screen space overlay would be possible...
    Thanks !
     
  6. bdeschryver

    bdeschryver

    Joined:
    Jun 13, 2013
    Posts:
    93
    Hey @SiliconDroid ,

    thanks for your help. This shader works nicely !
    But I am facing issues if I have one quad with your shader with a black background, and another quad with a logo image that should be on top (I want to have both in separate quads, not in one single image).
    How can I organize the order (which one is on top of the other) with your shader ? I tried having one or the other first in project hierarchy, but that does not help.

    Thanks

    PS: by the way, using the textmeshpro shaders for my black background also works to have it overlayed on top of all other geometry.
     
  7. SiliconDroid

    SiliconDroid

    Joined:
    Feb 20, 2017
    Posts:
    302
    Set the render queue priority per quads material, higher priorities will be drawn after lower.

    I've explored TextMeshPro more now and i love it, yes its shaders can do screenspace vr hack as we want.

    The way TextMeshPro shaders make bitmap behave like vector gfx is so cool.