Why does the 3D Text shader show specular at certain angles?

I’m using the 3D Text shader from the wiki. It solves the z-buffering problems that the standard 3d text shader had. But there are unwanted specular highlights in the transparent areas of the text that appear only when the camera is at certain angles to the 3D text objects.

I’m using two directional lights in the scene. Adjusting their direction or settings or using other light types has no effect.

Here is an example to illustrate:

alt text

…and at a slightly different camera angle:

alt text

Would like to know what’s causing this. Could this be solved by a simple change in the shader (including here so its handy)? If not, is there a certain part of the shader to investigate as a starting point?

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

SubShader {
   Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
   Lighting Off Cull Off ZWrite On Fog { Mode Off }
   Blend SrcAlpha OneMinusSrcAlpha
   Pass {
      Color [_Color]
      SetTexture [_MainTex] {
         combine primary, texture * primary

It’s not specular, it’s the background color.

I assume the dark rectangle with the small triangle at the bottom also uses a transparent shader? The problem is the transparency sorting between these two objects - at certain viewing angles it will fail, rendering the text first, and the dark shape afterwards. However, since the 3D Text shader uses “ZWrite On”, pixels that are actually behind the text are prevented from being rendered, because their z-test fails.

There are some ways to get around this, but a perfect solution working in all cases is difficult, and depend on the geometric situation in your scene.

Things you can try are:

  • change the shader to “ZWrite Off”. This might sometimes cause the text to vanish, though.
  • change the shader to “Queue”=“Transparent+1”. This might cause the text to be overlaid over other transparent objects, even when the text should be behind.
  • experiment with the two parameters of “ZOffset” (check the ShaderLab docs on the Unity site)
  • physically offset the 3D text from the dark object, so that it is closer to the viewer/ floating above its surface, to help the transparency sorting algorithm to fail less often
  • don’t use a transparent shader for the dark “background” geometry behind your text

And, indeed, another answer to my own question is to render text to a texture off-camera and combine text and background into one shader. Have done that route before on another project. But I wanted to get a better understanding of these sorting issues.