Search Unity

TextMesh Pro Hololens - Text only visible for one eye

Discussion in 'UGUI & TextMesh Pro' started by pflika, Sep 6, 2017.

  1. pflika

    pflika

    Joined:
    Jun 1, 2017
    Posts:
    4
    Hey,

    When I view a tmp ui text label on the hololens it is only displayed on the left eye, which makes it look quite strange!

    I have a Canvas set to world space and added the tmp text by right clicking.

    Is there some setting I'm missing?
     
  2. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Check Camera settings as I believe Target Display options were recently added which could be affecting this.

    upload_2017-9-6_12-25-35.png
     
  3. pflika

    pflika

    Joined:
    Jun 1, 2017
    Posts:
    4
    Hey Stephan,

    Thanks for the speedy response! I checked and it's set to Both.

    some build setting too
    upload_2017-9-7_10-58-9.png

    I'll try and reproduce it in a separate small repo project.
     
  4. pflika

    pflika

    Joined:
    Jun 1, 2017
    Posts:
    4
    found the option that does it!

    Of course when I made a new project it worked, so comparing the differences I found the setting that makes it only draw on one eye.

    Player Settings - Other Settings - Stereo Rendering Method - was set to Single Pass Instanced
    https://docs.unity3d.com/2017.2/Documentation/Manual/SinglePassStereoRenderingHoloLens.html

    It is set to Multi Pass by default but now you should be able to reproduce it.
    I'm guessing it's the tmp text shader that doesn't support instancing?
     
  5. pflika

    pflika

    Joined:
    Jun 1, 2017
    Posts:
    4
    If anyone else runs in to this problem and has to use single pass method the shader can easily be changed to enable instancing with help from these links:
    https://docs.unity3d.com/2017.2/Documentation/Manual/SinglePassStereoRenderingHoloLens.html
    https://docs.unity3d.com/2017.2/Documentation/Manual/GPUInstancing.html

    I'll attach the mobile version I stitched together here, it disables the nice editor gui to get the enable instancing option in the material
    Code (CSharp):
    1. // Simplified SDF shader:
    2. // - No Shading Option (bevel / bump / env map)
    3. // - No Glow Option
    4. // - Softness is applied on both side of the outline
    5.  
    6. Shader "TextMeshPro/Mobile/Distance Field" {
    7.  
    8. Properties {
    9.     _FaceColor            ("Face Color", Color) = (1,1,1,1)
    10.     _FaceDilate            ("Face Dilate", Range(-1,1)) = 0
    11.  
    12.     _OutlineColor        ("Outline Color", Color) = (0,0,0,1)
    13.     _OutlineWidth        ("Outline Thickness", Range(0,1)) = 0
    14.     _OutlineSoftness    ("Outline Softness", Range(0,1)) = 0
    15.  
    16.     _UnderlayColor        ("Border Color", Color) = (0,0,0,.5)
    17.     _UnderlayOffsetX     ("Border OffsetX", Range(-1,1)) = 0
    18.     _UnderlayOffsetY     ("Border OffsetY", Range(-1,1)) = 0
    19.     _UnderlayDilate        ("Border Dilate", Range(-1,1)) = 0
    20.     _UnderlaySoftness     ("Border Softness", Range(0,1)) = 0
    21.  
    22.     _WeightNormal        ("Weight Normal", float) = 0
    23.     _WeightBold            ("Weight Bold", float) = .5
    24.  
    25.     _ShaderFlags        ("Flags", float) = 0
    26.     _ScaleRatioA        ("Scale RatioA", float) = 1
    27.     _ScaleRatioB        ("Scale RatioB", float) = 1
    28.     _ScaleRatioC        ("Scale RatioC", float) = 1
    29.  
    30.     _MainTex            ("Font Atlas", 2D) = "white" {}
    31.     _TextureWidth        ("Texture Width", float) = 512
    32.     _TextureHeight        ("Texture Height", float) = 512
    33.     _GradientScale        ("Gradient Scale", float) = 5
    34.     _ScaleX                ("Scale X", float) = 1
    35.     _ScaleY                ("Scale Y", float) = 1
    36.     _PerspectiveFilter    ("Perspective Correction", Range(0, 1)) = 0.875
    37.  
    38.     _VertexOffsetX        ("Vertex OffsetX", float) = 0
    39.     _VertexOffsetY        ("Vertex OffsetY", float) = 0
    40.  
    41.     _ClipRect            ("Clip Rect", vector) = (-32767, -32767, 32767, 32767)
    42.     _MaskSoftnessX        ("Mask SoftnessX", float) = 0
    43.     _MaskSoftnessY        ("Mask SoftnessY", float) = 0
    44.    
    45.     _StencilComp        ("Stencil Comparison", Float) = 8
    46.     _Stencil            ("Stencil ID", Float) = 0
    47.     _StencilOp            ("Stencil Operation", Float) = 0
    48.     _StencilWriteMask    ("Stencil Write Mask", Float) = 255
    49.     _StencilReadMask    ("Stencil Read Mask", Float) = 255
    50.    
    51.     _ColorMask            ("Color Mask", Float) = 15
    52. }
    53.  
    54. SubShader {
    55.     Tags
    56.     {
    57.         "Queue"="Transparent"
    58.         "IgnoreProjector"="True"
    59.         "RenderType"="Transparent"
    60.     }
    61.  
    62.  
    63.     Stencil
    64.     {
    65.         Ref [_Stencil]
    66.         Comp [_StencilComp]
    67.         Pass [_StencilOp]
    68.         ReadMask [_StencilReadMask]
    69.         WriteMask [_StencilWriteMask]
    70.     }
    71.  
    72.     Cull [_CullMode]
    73.     ZWrite Off
    74.     Lighting Off
    75.     Fog { Mode Off }
    76.     ZTest [unity_GUIZTestMode]
    77.     Blend One OneMinusSrcAlpha
    78.     ColorMask [_ColorMask]
    79.  
    80.     Pass {
    81.         CGPROGRAM
    82.         #pragma vertex VertShader
    83.         #pragma fragment PixShader
    84.         #pragma shader_feature __ OUTLINE_ON
    85.         #pragma shader_feature __ UNDERLAY_ON UNDERLAY_INNER
    86.         #pragma multi_compile_instancing  
    87.  
    88.         #include "UnityCG.cginc"
    89.         #include "UnityUI.cginc"
    90.         #include "TMPro_Properties.cginc"
    91.  
    92.         struct vertex_t {
    93.             float4    vertex            : POSITION;
    94.             float3    normal            : NORMAL;
    95.             fixed4    color            : COLOR;
    96.             float2    texcoord0        : TEXCOORD0;
    97.             float2    texcoord1        : TEXCOORD1;
    98.             UNITY_VERTEX_INPUT_INSTANCE_ID
    99.         };
    100.  
    101.         struct pixel_t {
    102.             float4    vertex            : SV_POSITION;
    103.             fixed4    faceColor        : COLOR;
    104.             fixed4    outlineColor    : COLOR1;
    105.             float4    texcoord0        : TEXCOORD0;            // Texture UV, Mask UV
    106.             half4    param            : TEXCOORD1;            // Scale(x), BiasIn(y), BiasOut(z), Bias(w)
    107.             half4    mask            : TEXCOORD2;            // Position in clip space(xy), Softness(zw)
    108.         #if (UNDERLAY_ON | UNDERLAY_INNER)
    109.             float4    texcoord1        : TEXCOORD3;            // Texture UV, alpha, reserved
    110.             half2    underlayParam    : TEXCOORD4;            // Scale(x), Bias(y)
    111.         #endif
    112.             UNITY_VERTEX_INPUT_INSTANCE_ID
    113.             UNITY_VERTEX_OUTPUT_STEREO
    114.         };
    115.  
    116.         UNITY_INSTANCING_CBUFFER_START(MyProperties)
    117.             UNITY_DEFINE_INSTANCED_PROP(float4, _Color)
    118.         UNITY_INSTANCING_CBUFFER_END
    119.  
    120.         pixel_t VertShader(vertex_t input)
    121.         {
    122.             UNITY_SETUP_INSTANCE_ID(input);
    123.  
    124.             float bold = step(input.texcoord1.y, 0);
    125.  
    126.             float4 vert = input.vertex;
    127.             vert.x += _VertexOffsetX;
    128.             vert.y += _VertexOffsetY;
    129.             float4 vPosition = UnityObjectToClipPos(vert);
    130.  
    131.             float2 pixelSize = vPosition.w;
    132.             pixelSize /= float2(_ScaleX, _ScaleY) * abs(mul((float2x2)UNITY_MATRIX_P, _ScreenParams.xy));
    133.            
    134.             float scale = rsqrt(dot(pixelSize, pixelSize));
    135.             scale *= abs(input.texcoord1.y) * _GradientScale * 1.5;
    136.             if(UNITY_MATRIX_P[3][3] == 0) scale = lerp(abs(scale) * (1 - _PerspectiveFilter), scale, abs(dot(UnityObjectToWorldNormal(input.normal.xyz), normalize(WorldSpaceViewDir(vert)))));
    137.  
    138.             float weight = lerp(_WeightNormal, _WeightBold, bold) / 4.0;
    139.             weight = (weight + _FaceDilate) * _ScaleRatioA * 0.5;
    140.  
    141.             float layerScale = scale;
    142.  
    143.             scale /= 1 + (_OutlineSoftness * _ScaleRatioA * scale);
    144.             float bias = (0.5 - weight) * scale - 0.5;
    145.             float outline = _OutlineWidth * _ScaleRatioA * 0.5 * scale;
    146.  
    147.             float opacity = input.color.a;
    148.         #if (UNDERLAY_ON | UNDERLAY_INNER)
    149.                 opacity = 1.0;
    150.         #endif
    151.  
    152.             fixed4 faceColor = fixed4(input.color.rgb, opacity) * _FaceColor;
    153.             faceColor.rgb *= faceColor.a;
    154.  
    155.             fixed4 outlineColor = _OutlineColor;
    156.             outlineColor.a *= opacity;
    157.             outlineColor.rgb *= outlineColor.a;
    158.             outlineColor = lerp(faceColor, outlineColor, sqrt(min(1.0, (outline * 2))));
    159.  
    160.         #if (UNDERLAY_ON | UNDERLAY_INNER)
    161.  
    162.             layerScale /= 1 + ((_UnderlaySoftness * _ScaleRatioC) * layerScale);
    163.             float layerBias = (.5 - weight) * layerScale - .5 - ((_UnderlayDilate * _ScaleRatioC) * .5 * layerScale);
    164.  
    165.             float x = -(_UnderlayOffsetX * _ScaleRatioC) * _GradientScale / _TextureWidth;
    166.             float y = -(_UnderlayOffsetY * _ScaleRatioC) * _GradientScale / _TextureHeight;
    167.             float2 layerOffset = float2(x, y);
    168.         #endif
    169.  
    170.             // Generate UV for the Masking Texture
    171.             float4 clampedRect = clamp(_ClipRect, -2e10, 2e10);
    172.             float2 maskUV = (vert.xy - clampedRect.xy) / (clampedRect.zw - clampedRect.xy);
    173.  
    174.             // Structure for pixel shader
    175.             pixel_t output;
    176.             UNITY_TRANSFER_INSTANCE_ID(input, output);
    177.             UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
    178.             output.vertex = vPosition;
    179.             output.faceColor = faceColor;
    180.             output.outlineColor = outlineColor;
    181.             output.texcoord0 = float4(input.texcoord0.x, input.texcoord0.y, maskUV.x, maskUV.y);
    182.             output.param = half4(scale, bias - outline, bias + outline, bias);
    183.             output.mask = half4(vert.xy * 2 - clampedRect.xy - clampedRect.zw, 0.25 / (0.25 * half2(_MaskSoftnessX, _MaskSoftnessY) + pixelSize.xy));
    184. #if (UNDERLAY_ON | UNDERLAY_INNER)
    185.             output.texcoord1 = float4(input.texcoord0 + layerOffset, input.color.a, 0);
    186.             output.underlayParam = half2(layerScale, layerBias);
    187. #endif
    188.  
    189.             return output;
    190.         }
    191.  
    192.  
    193.         // PIXEL SHADER
    194.         fixed4 PixShader(pixel_t input) : SV_Target
    195.         {
    196.             //UNITY_SETUP_INSTANCE_ID(input); //// necessary only if any instanced properties are going to be accessed in the fragment Shader.
    197.             //UNITY_ACCESS_INSTANCED_PROP(_Color)
    198.            
    199.             half d = tex2D(_MainTex, input.texcoord0.xy).a * input.param.x;
    200.             half4 c = input.faceColor * saturate(d - input.param.w);
    201.  
    202.         #ifdef OUTLINE_ON
    203.             c = lerp(input.outlineColor, input.faceColor, saturate(d - input.param.z));
    204.             c *= saturate(d - input.param.y);
    205.         #endif
    206.  
    207.         #if UNDERLAY_ON
    208.             d = tex2D(_MainTex, input.texcoord1.xy).a * input.underlayParam.x;
    209.             c += float4(_UnderlayColor.rgb * _UnderlayColor.a, _UnderlayColor.a) * saturate(d - input.underlayParam.y) * (1 - c.a);
    210.         #endif
    211.  
    212.         #if UNDERLAY_INNER
    213.             half sd = saturate(d - input.param.z);
    214.             d = tex2D(_MainTex, input.texcoord1.xy).a * input.underlayParam.x;
    215.             c += float4(_UnderlayColor.rgb * _UnderlayColor.a, _UnderlayColor.a) * (1 - saturate(d - input.underlayParam.y)) * sd * (1 - c.a);
    216.         #endif
    217.  
    218.         #if UNITY_VERSION < 530
    219.             // Unity 5.2 2D Rect Mask Support
    220.             if (_UseClipRect)
    221.             {
    222.                 half2 m = saturate((_ClipRect.zw - _ClipRect.xy - abs(input.mask.xy)) * input.mask.zw);
    223.                 c *= m.x * m.y;
    224.             }
    225.         #else
    226.             // Alternative implementation to UnityGet2DClipping with support for softness.
    227.             half2 m = saturate((_ClipRect.zw - _ClipRect.xy - abs(input.mask.xy)) * input.mask.zw);
    228.             c *= m.x * m.y;
    229.         #endif
    230.  
    231.         #if (UNDERLAY_ON | UNDERLAY_INNER)
    232.             c *= input.texcoord1.z;
    233.         #endif
    234.  
    235.             clip(c.a - 0.001);
    236.  
    237.             return c;
    238.         }
    239.         ENDCG
    240.     }
    241. }
    242.  
    243. //CustomEditor "TMPro.EditorUtilities.TMP_SDFShaderGUI"
    244. }
    245.  
     
    arielfel likes this.
  6. MadeFromPolygons

    MadeFromPolygons

    Joined:
    Oct 5, 2013
    Posts:
    3,982
    Why in gods name has this not been fixed in TMP release versions?

    Im pretty ****ed off that I still have to navigate to a thread from 2017 to fix this.

    @Stephan_B can someone on unity side please make this fix go in, its silly that you can select single pass and then break an official package. Certainly after 1.5 years I should not be having to manually edit a shader to get something as simple as stereo rendering of text to work.
     
    Pycorax likes this.
  7. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    The latest release of the TMP package for Unity 2018.3 (1.4.0-preview.3a) includes revised shaders that support Stereo rendering.
     
    arielfel and MadeFromPolygons like this.
  8. MadeFromPolygons

    MadeFromPolygons

    Joined:
    Oct 5, 2013
    Posts:
    3,982
    For some reason they did not show up in my package list until I restarted the editor, but can now confirm they are there and working as expected! Thankyou :)
     
    Stephan_B likes this.
  9. DeloitteCam

    DeloitteCam

    Joined:
    Jan 23, 2018
    Posts:
    22
    Did this somehow not make it into the final versions? We are on TMP 2.0.0 and had the same issue on Magic Leap. I looked at the shaders but couldn't see any stereo instance macros. Reverted to TMP 1.4.0 release version and that didn't seem to change anything. Ended using some older modified ones.
     
  10. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    The shaders are included in the updated TMP Essential Resources which you will need to import.
     
  11. MadeFromPolygons

    MadeFromPolygons

    Joined:
    Oct 5, 2013
    Posts:
    3,982
    This is still an issue in latest TMP, the TMP essential resources you mentioned do not stop this happening. Empty project, latest TMP package + Hololens 1.
     
  12. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Version 1.4.0 and 2.0.0 did include some updated shaders. Version 1.4.1-preview.1 and 2.0.1-preview.1 adds the overlay shaders to this list.

    Make sure you are using the correct package and TMP Essential Resources.
     
  13. Dimn721

    Dimn721

    Joined:
    Mar 30, 2017
    Posts:
    9
    I was able to update the TMP Essential Resouces to fix text showing up in one eye but I'm having the same issue now with sprites. Is there a fix for the sprite material as well?
     
  14. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    The sprite shader was derived from the Unity Sprite shader (a while back) I would suggest getting the latest Unity shaders to see if the sprite shader was updated to support stereo rendering. The older version could be revised to include those changes.

    P.S. I am out of office right now otherwise I would look myself. Let me know what you find and I can make the necessary tweaks for the next release.
     
  15. Dimn721

    Dimn721

    Joined:
    Mar 30, 2017
    Posts:
    9
    I don't know a whole lot about shader code but I was able to get something working by doing what you said, I copied over the newest Unity Sprite shader that does work for stereo into the TMP sprite shader replacing most of it. I left in the stencil stuff so it would still work with ui masking. Seems to work this way.

    Code (CSharp):
    1. Shader "TextMeshPro/Sprite"
    2. {
    3.     Properties
    4.     {
    5.         [PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}
    6.         _Color ("Tint", Color) = (1,1,1,1)
    7.        
    8.         [MaterialToggle] PixelSnap("Pixel snap", Float) = 0
    9.         [HideInInspector] _RendererColor("RendererColor", Color) = (1,1,1,1)
    10.         [HideInInspector] _Flip("Flip", Vector) = (1,1,1,1)
    11.         [PerRendererData] _AlphaTex("External Alpha", 2D) = "white" {}
    12.         [PerRendererData] _EnableExternalAlpha("Enable External Alpha", Float) = 0
    13.  
    14.         _StencilComp ("Stencil Comparison", Float) = 8
    15.         _Stencil ("Stencil ID", Float) = 0
    16.         _StencilOp ("Stencil Operation", Float) = 0
    17.         _StencilWriteMask ("Stencil Write Mask", Float) = 255
    18.         _StencilReadMask ("Stencil Read Mask", Float) = 255
    19.  
    20.         _ColorMask ("Color Mask", Float) = 15
    21.         _ClipRect ("Clip Rect", vector) = (-32767, -32767, 32767, 32767)
    22.  
    23.         [Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
    24.     }
    25.  
    26.     SubShader
    27.     {
    28.         Tags
    29.         {
    30.             "Queue"="Transparent"
    31.             "IgnoreProjector"="True"
    32.             "RenderType"="Transparent"
    33.             "PreviewType"="Plane"
    34.             "CanUseSpriteAtlas"="True"
    35.         }
    36.        
    37.         Stencil
    38.         {
    39.             Ref [_Stencil]
    40.             Comp [_StencilComp]
    41.             Pass [_StencilOp]
    42.             ReadMask [_StencilReadMask]
    43.             WriteMask [_StencilWriteMask]
    44.         }
    45.  
    46.         Cull Off
    47.         Lighting Off
    48.         ZWrite Off
    49.         ZTest [unity_GUIZTestMode]
    50.         Blend One OneMinusSrcAlpha
    51.         ColorMask [_ColorMask]
    52.  
    53.         Pass
    54.         {
    55.         CGPROGRAM
    56.             #pragma vertex SpriteVert
    57.             #pragma fragment SpriteFrag
    58.             #pragma target 2.0
    59.             #pragma multi_compile_instancing
    60.             #pragma multi_compile_local _ PIXELSNAP_ON
    61.             #pragma multi_compile _ ETC1_EXTERNAL_ALPHA
    62.             #include "UnitySprites.cginc"
    63.         ENDCG
    64.         }
    65.     }
    66. }
    67.  
     
  16. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595

    Cool. I'll take a closer look over the next few days and then add a new revised shader for the sprites.

    Thank you for taking the time to investigate that.
     
  17. Nyanpas

    Nyanpas

    Joined:
    Dec 29, 2016
    Posts:
    406
    I attempted this on a HL1 and it didn't work with single pass instanced in Unity 2019.2+ using MRTK...

    [edit] It done did work with this, though:

     
    Minchuilla and MadeFromPolygons like this.
  18. Ejvik

    Ejvik

    Joined:
    Dec 4, 2019
    Posts:
    2
    Hi guys,
    I have this problem and nothing above helped me to fix it. With certain settings, I can see a canvas with text only on the right eye and I can't get it on both.
    I tried to play with a setting like Target Display, Target Eye, I tried Multi Pass, Single Pass and Single Pass Instanced, I tried to add two cameras one for each eye,.. As you can see there is already a lot of combinations you can set but nothing of what I tried worked. I got only right eye working (even when the camera was set for left eye) or none but never both.
    Unity version 2019.2.8f1. Hololens gen1 OS build 10.0.17763.806, TMP 2.0.1.
    I would appreciate any kind of help.
     
  19. Ejvik

    Ejvik

    Joined:
    Dec 4, 2019
    Posts:
    2
    problem solved.
    The canvas has to be set to screen space - camera and the main camera on both eyes. Like this, it works with both Multi pass and Single pass.
     
    Stephan_B likes this.
  20. Loden_Heathen

    Loden_Heathen

    Joined:
    Sep 1, 2012
    Posts:
    480
    I can confirm that this is still an issue in 2020 with TMPro sprite
    The fix of mucking with the shaders I assume will work but ya this should have been fixed when the text rendering was fixed

    The shader fix above does seem to work
     
    Last edited: Aug 20, 2020
  21. Bshsf_9527

    Bshsf_9527

    Joined:
    Sep 6, 2017
    Posts:
    43
    mrtk provide a shader to fix this issue,you can find this shader :"Mixed Reality Toolkit/TextMeshPro"
     
    digitalblend likes this.
  22. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    TMP shaders were updated a while back but these new shaders are contained in the updated TMP Essential Resources. Please re-import the TMP Essential Resources from one of the latest release of the TMP package.
     
    noemis likes this.
  23. FloBeber

    FloBeber

    Joined:
    Jun 9, 2015
    Posts:
    166
    @Stephan_B

    FYI, just ran into a couple of issue with Sprites in TMP 3.0.3:
    1. using <sprite> inside <mark> triggers a null pointer exception
    2. TMP_Sprite does not support Stereo rendering.

    Hope that helps!
     
  24. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    I posted an updated TMP sprite shader in another thread (which I cannot find right now) so I linked that shader again here.

    Replace the existing TMP_Sprite.shader by this new one and Stereo rendering should work as expected. Be sure to copy outside of Unity so the same .meta / GUID is preserved.

    With respect to the null reference, see if making the change in the following thread resolves that.
     

    Attached Files:

    FloBeber likes this.