Simple white text on black background as UI in HMD

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 !

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.

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:

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//   ____ ___ _     ___ ____ ___  _   _   ____  ____   ___ ___ ____
//  / ___|_ _| |   |_ _/ ___/ _ \| \ | | |  _ \|  _ \ / _ \_ _|  _ \
//  \___ \| || |    | | |  | | | |  \| | | | | | |_) | | | | || | | |
//   ___) | || |___ | | |__| |_| | |\  | | |_| |  _ <| |_| | || |_| |
//  |____/___|_____|___\____\___/|_| \_| |____/|_| \_\\___/___|____/
//
//    MOBILE: UNLIT COLOR WITH ALPHA
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Shader "SiliconDroid/Mobile_UnlitAlphaTextureNoZ"
{
    Properties
    {
        _Alpha ("Alpha", Range (0.0,1.0)) = 1.0
        _MainTex ("Base (RGB) Transparency (A)", 2D) = "" { }
    }

    Category
    {
        Lighting Off
        ZWrite Off
        ZTest Off
        Cull back
        Blend SrcAlpha OneMinusSrcAlpha
        Tags {Queue=Transparent}
        SubShader
        {
            Pass
            {
                SetTexture [_MainTex]
                {
                   constantColor (1, 1, 1, [_Alpha])
                   combine texture * constant
                }
            }
        }
    }
}

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:

// modulate float fAlpha using coroutine etc.
oMyMaterial.SetFloat("_Alpha", fAlpha);

Thanks for that !
Would you confirm that screen space overlay is definitely not possible with VR ? (and shown in the headset)

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 !

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.

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.