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...
我正在使用一个文本网格将文本放置在一个3D对象上,但是正如你们所知道的,文本网格没有任何法线……
http://docs.unity3d.com/Documentation/Components/class-TextMesh.html
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.
…所以它不能正确地发光。我做了一个搜索,发现很多人在使用3D文本网格时遇到了麻烦,因为它没有任何法线,但是我还没有找到向文本网格对象添加法线的解决方案,所以这是我的问题。
How can I add a normal to a text mesh so that it lights correctly?
如何在文本网格中添加一个法线,使其正确地发光?
Thanks so much in advance for your wisdom!
非常感谢您的智慧!
1 个解决方案
#1
6
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.
我做了一些类似的事情来点燃3D纹理。我希望我的回答不过分。所以这段代码是我之前写的一个技巧,它的效率很低,并且只支持一个方向光(这里有用的cg照明tuts)。希望这足够让你开始。
To create a 3D texture using my code below you have to go through a little more work:
要使用我下面的代码创建一个3D纹理,你需要做更多的工作:
- Create an empty game object
- 创建一个空的游戏对象
- Attach Component->Mesh->Text Mesh
- 附加组件- >网- >文本网格
- Attach Component TextMeshNormals (included below)
- 附加组件文本法线(包括以下)
- Attach Component->Mesh->Mesh Renderer
- 附加组件- >网- >网格渲染器
- Assign a material to the Mesh Renderer that uses my GUI/LitText shader below
- 为使用下面的GUI/LitText着色器的网格渲染器分配一个材质
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.
在着色器中,您将注意到一个文本normal属性。在实践中,您将有您的gameObject的Update()方法,该方法将使用文本所面向的方向更新_Normal属性,以反映方向的变化。文本是平面的,所以我们只需要1法线。为了测试我手动设置了正常到(0,0,-1,1),因为默认的文本网格是向下的-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:
4.5更新统一。X使用这个稍微更新的版本:
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
}
}
}
#1
6
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.
我做了一些类似的事情来点燃3D纹理。我希望我的回答不过分。所以这段代码是我之前写的一个技巧,它的效率很低,并且只支持一个方向光(这里有用的cg照明tuts)。希望这足够让你开始。
To create a 3D texture using my code below you have to go through a little more work:
要使用我下面的代码创建一个3D纹理,你需要做更多的工作:
- Create an empty game object
- 创建一个空的游戏对象
- Attach Component->Mesh->Text Mesh
- 附加组件- >网- >文本网格
- Attach Component TextMeshNormals (included below)
- 附加组件文本法线(包括以下)
- Attach Component->Mesh->Mesh Renderer
- 附加组件- >网- >网格渲染器
- Assign a material to the Mesh Renderer that uses my GUI/LitText shader below
- 为使用下面的GUI/LitText着色器的网格渲染器分配一个材质
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.
在着色器中,您将注意到一个文本normal属性。在实践中,您将有您的gameObject的Update()方法,该方法将使用文本所面向的方向更新_Normal属性,以反映方向的变化。文本是平面的,所以我们只需要1法线。为了测试我手动设置了正常到(0,0,-1,1),因为默认的文本网格是向下的-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:
4.5更新统一。X使用这个稍微更新的版本:
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
}
}
}