3D text that takes the depth buffer into account

Hey guys is there a way to make the builtin 3D text take the depth buffer into account so it’s clipped by objects in front of it?

Make a new GUI/Text Shader that’s a copy of the built-in one, but with “ZTest Always” removed, and use that.

–Eric

2 Likes

Cool, thanks man I’ll give it a shot

Did as instructed:

  • “Internal-GUITextureClipText.shader” version 4.1.2 of built in shaders
  • Removed all 3 occurences of “ZTest Always”

Nothing renders…

Nice 5-year thread bump… http://wiki.unity3d.com/index.php?title=3DText

–Eric

Can I make a 3d text with rich-edit support that is occluded by geometry ?

My default shader does not contain ZTest Always in it.

Can’t be bothered to go through wiki sign-up and anyway this thread is higher in google results…

The shader on the linked wiki page did not work in Unity 4. Color of 3DText is set with vertex color, not even sure why their font shader requires a font color. So, this is what you want. Without Cull specified it does cull the back faces, so if you want double-side just put Cull Off in there under ZWrite Off

Shader "GUI/3DText"
{
    Properties
    {
        _MainTex ("Font Texture", 2D) = "white" {}
    }

    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent"}
     
        Pass
        {
            Blend SrcAlpha OneMinusSrcAlpha
            ZWrite Off
         
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            sampler2D _MainTex;
         
            struct v2f {
                float4 pos : SV_POSITION;
                fixed4 color : COLOR;
                float2 uv : TEXCOORD0;
            };
         
            struct appdata {
                float4 vertex : POSITION;
                fixed4 color : COLOR;
                float2 texcoord : TEXCOORD0;
            };

            float4 _MainTex_ST;
         
            v2f vert (appdata v)
            {
                v2f o;
                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
                o.color = v.color;
                o.uv    = TRANSFORM_TEX (v.texcoord, _MainTex);
                return o;
            }
         
            fixed4 frag (v2f o) : COLOR
            {
                // this gives us text or not based on alpha, apparently
                o.color.a  *= tex2D( _MainTex, o.uv ).a;
                return o.color;
            }
            ENDCG
        }
    }
}
5 Likes

ddf,

“Can’t be bothered to go through wiki sign-up”

couldn’t agree more - thanks a million!

1 Like

I slightly modified the script above of @ddf so that you can color the type. (Hopefully I did this in an OK way!)

// http://forum.unity3d.com/threads/3d-text-that-takes-the-depth-buffer-into-account.9931/
// slightly modified so that it has a color parameter,
// start with white sprites and you can color them
// if having trouble making font sprite sets http://answers.unity3d.com/answers/1105527/view.html

Shader "GUI/Color3DText"
{
    Properties
    {
        _MainTex ("Font Texture", 2D) = "white" {}
       
        _Colorize ("Colorize", Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent"}
    
        Pass
        {
            Blend SrcAlpha OneMinusSrcAlpha
            ZWrite Off
        
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            sampler2D _MainTex;
           
            fixed4 _Colorize;
           
            struct v2f {
                float4 pos : SV_POSITION;
                fixed4 color : COLOR;
                float2 uv : TEXCOORD0;
            };
        
            struct appdata {
                float4 vertex : POSITION;
                fixed4 color : COLOR;
                float2 texcoord : TEXCOORD0;
            };
            float4 _MainTex_ST;
        
            v2f vert (appdata v)
            {
                v2f o;
                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
                o.color = v.color;
                o.uv    = TRANSFORM_TEX (v.texcoord, _MainTex);
                return o;
            }
        
            fixed4 frag (v2f o) : COLOR
            {
                // this gives us text or not based on alpha, apparently
                o.color.a  *= tex2D( _MainTex, o.uv ).a;
               
                o.color *= _Colorize;
               
                return o.color;
            }
            ENDCG
        }
    }
}
1 Like

Hello, thanks for your shader it saved my day. What if I would need the Cull Back? I’ve tried to add that, but it doesn’t work. Am I missing something?

Howdy All,

Same experience. Shader fixes occlusion.
Funny: this was same solution i used 5 years ago when i tried used text in Unity then.
Returning to Unity now, I assumed it would be fixed.

Are there any Unity staff listening to this thread: why is this not already part of basic functionality?

respects,
Jhav

3 Likes

“Are there any Unity staff listening to this thread: why is this not already part of basic functionality?”

+1 This is bizarre to me too

1 Like

And now the website that everyone’s linking to with the shader is down :confused:

Here is the solution updated to Unity 2017.1.0f3

Shader "GUI/Depth Text Shader" {
    Properties {
        _MainTex ("Font Texture", 2D) = "white" {}
        _Color ("Text Color", Color) = (1,1,1,1)
    }

    SubShader {

        Tags {
            "Queue"="Transparent"
            "IgnoreProjector"="True"
            "RenderType"="Transparent"
            "PreviewType"="Plane"
        }
        Lighting Off Cull Off ZTest LEqual ZWrite Off
        Blend SrcAlpha OneMinusSrcAlpha

        Pass {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile _ UNITY_SINGLE_PASS_STEREO STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON
            #include "UnityCG.cginc"

            struct appdata_t {
                float4 vertex : POSITION;
                fixed4 color : COLOR;
                float2 texcoord : TEXCOORD0;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };

            struct v2f {
                float4 vertex : SV_POSITION;
                fixed4 color : COLOR;
                float2 texcoord : TEXCOORD0;
                UNITY_VERTEX_OUTPUT_STEREO
            };

            sampler2D _MainTex;
            uniform float4 _MainTex_ST;
            uniform fixed4 _Color;

            v2f vert (appdata_t v)
            {
                v2f o;
                UNITY_SETUP_INSTANCE_ID(v);
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.color = v.color * _Color;
                o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex);
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = i.color;
                col.a *= tex2D(_MainTex, i.texcoord).a;
                return col;
            }
            ENDCG
        }
    }
}
1 Like

Thanks :slight_smile: But errr I’m not sure how to use it!

I tried creating a shader to paste this into but wasn’t sure which one?
And then what do I do with it afterwards, etc?

Thanks in advance.

Standard Surface Shader is the right choice, after that copy paste my code and you will have all ready to use in your materials. You will see this new shader on GUI/Depth Text Shader.

You have to assign font texture to this shader in material editor.
3170635--241543--Sin título.png

1 Like

Hey GTRuiz, I also want to make this work, but I’m really not getting this.

So I created a new Standard Surface Shader and I copied that code into it. I hope that’s correct … I also imported a font (containing a font material and a font texture). I don’t get the next step though, the one where you tell us to assign a font texture to the shader in material editor. Can you be just a bit more specific with this part?

Edit: I think I figured it out.

Yeah I also don’t understand what to do next. What did you do, iggy?

Sorry guys… I thought it was clear. You have to do this steps.

1º - Create Standard Surface Shader and copy my code.
2º - Import your favorite Font.
3º - Create a new Material.
4º - In this new Material select GUI/Depth Text Shader.
5º - Assign Font texture to texture slot in this Material.
6º - Create a 3D Text on your scene.
7º - Assign your favourite Font to this 3D Text.
8º - Assign in Mesh Renderer component your configured Material.
9º - Enjoy your 3D Text working fine!! :smile:

Everything is tested and it is working for me, good luck!

4 Likes