I'm using a text mesh to place text on a 3D object, but as you all know, the text mesh does not have any normals...
http://docs.unity3d.com/Documentation/Components/class-TextMesh.html
...so it does not light correctly. I've done a search and found many people having trouble with lighting 3D text mesh because of it doesn't have any normals, but I haven't found a solution to adding normals to a text mesh object, so that is my question.
How can I add a normal to a text mesh so that it lights correctly?
Thanks so much in advance for your wisdom!
You can't drag a UI material directly onto UI pieces, but, for instance, the Text (Script) area in the inspector—the same place you enter the text you want displayed in that box—has a property toward the bottom called "Material." You can drag a new material into there.
To create an empty TextMesh Pro font asset, select a Unity font Asset and then select Asset > Create > TextMeshPro > Font Asset from the menu.
Now the problem is, that I want to change the text of the TextMeshPro in the gun script. Simplest solution: create "public TextMeshPro textMesh". Drag the TextMeshPro object to the script in the inspector and youre good to go.
TextMesh Pro is a replacement for Unity's existing text components like Text Mesh and UI Text. TextMesh Pro uses Signed Distance Field (SDF) as its primary text rendering pipeline making it possible to render text cleanly at any point size and resolution.
I did something similar for lighting a 3D texture. I hope my answer isn't overkill. So this code was a hack I wrote awhile back, it's inefficient and only supports a single directional light (helpful cg lighting tuts here). Hopefully this is enough to get you started.
To create a 3D texture using my code below you have to go through a little more work:
In the shader you'll notice a text normal attribute. In practice you would have your gameObject's Update() method update the _Normal
property with the direction the text is facing so that it reflects a change in orientation. The text is planar so 1 normal is all we need. To test I manually set the normal to (0,0,-1,1), since the default Text Mesh faces down -Z.
Because this script doesn't run in the editor, your text won't show up until you run a scene in preview.
The shader:
Shader "GUI/LitText" {
Properties {
_MainTex ("Font Texture", 2D) = "white" {}
_Color ("Text Color", Color) = (1,1,1,1)
_Normal ("Text Normal",Vector) = (0,0,0,1)
}
SubShader {
Blend SrcAlpha OneMinusSrcAlpha
Pass {
Color [_Color]
SetTexture [_MainTex] {
combine primary, texture * primary
}
}
pass {
Tags { "LightMode" = "ForwardBase" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
uniform sampler2D _MainTex;
uniform float4 _Color; // define shader property for shaders
uniform float4 _Normal;
// The following built-in uniforms (apart from _LightColor0)
// are defined in "UnityCG.cginc", which could be #included
uniform float4 unity_Scale; // w = 1/scale; see _World2Object
uniform float3 _WorldSpaceCameraPos;
uniform float4x4 _Object2World; // model matrix
uniform float4x4 _World2Object; // inverse model matrix
// (all but the bottom-right element have to be scaled
// with unity_Scale.w if scaling is important)
uniform float4 _WorldSpaceLightPos0;
// position or direction of light source
uniform float4 _LightColor0;
// color of light source (from "Lighting.cginc")
struct vertexInput {
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
};
struct vertexOutput {
float4 pos : SV_POSITION;
float4 col : COLOR;
float4 tex : TEXCOORD0;
};
vertexOutput vert(vertexInput input)
{
vertexOutput output;
float4x4 modelMatrix = _Object2World;
float4x4 modelMatrixInverse = _World2Object;
float3 normalDirection = normalize(float3(mul(_Normal, modelMatrixInverse)));
float3 lightDirection = normalize(float3(_WorldSpaceLightPos0));
float3 diffuseReflection = float3(_LightColor0) * float3(_Color)
* max(0.0, dot(normalDirection, lightDirection));
output.col = float4(diffuseReflection, 1.0);
output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
output.tex = input.texcoord;
return output;
}
float4 frag(vertexOutput input) : COLOR
{
half4 color = tex2D(_MainTex, float2(input.tex));
// use color.a to get alpha from text texture, rgb comes from vertex shader
return float4(input.col.r,input.col.g,input.col.b,color.a);
}
ENDCG
}
}
}
And the helper script:
public class TextMeshNormals : MonoBehaviour {
private TextMesh textMesh;
// Use this for initialization
void Start () {
// reassign font texture to our material
textMesh = transform.GetComponent<TextMesh>();
renderer.material.mainTexture = textMesh.font.material.mainTexture;
}
}
Update Unity 4.5.X use this slightly updated version:
Shader "GUI/LitText" {
Properties {
_MainTex ("Font Texture", 2D) = "white" {}
_Color ("Text Color", Color) = (1,1,1,1)
_Normal ("Text Normal",Vector) = (0,0,0,1)
}
SubShader {
Blend SrcAlpha OneMinusSrcAlpha
Pass {
Color [_Color]
SetTexture [_MainTex] {
combine primary, texture * primary
}
}
pass {
Tags { "LightMode" = "ForwardBase" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
uniform sampler2D _MainTex;
uniform float4 _Color; // define shader property for shaders
uniform float4 _Normal;
uniform float4 _LightColor0;
// color of light source (from "Lighting.cginc")
struct vertexInput {
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
};
struct vertexOutput {
float4 pos : SV_POSITION;
float4 col : COLOR;
float4 tex : TEXCOORD0;
};
vertexOutput vert(vertexInput input)
{
vertexOutput output;
float4x4 modelMatrix = _Object2World;
float4x4 modelMatrixInverse = _World2Object;
float3 normalDirection = normalize(float3(mul(_Normal, modelMatrixInverse)));
float3 lightDirection = normalize(float3(_WorldSpaceLightPos0));
float3 diffuseReflection = float3(_LightColor0) * float3(_Color)
* max(0.0, dot(normalDirection, lightDirection));
output.col = float4(diffuseReflection, 1.0);
output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
output.tex = input.texcoord;
return output;
}
float4 frag(vertexOutput input) : COLOR
{
half4 color = tex2D(_MainTex, float2(input.tex));
// use color.a to get alpha from text texture, rgb comes from vertex shader
return float4(input.col.r,input.col.g,input.col.b,color.a);
}
ENDCG
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With