如何为文本网格添加法线以使其正确点亮?

时间:2013-04-26 03:53:41

标签: unity3d lighting normals

我正在使用文本网格在3D对象上放置文字,但众所周知,文本网格没有任何法线......

http://docs.unity3d.com/Documentation/Components/class-TextMesh.html

...所以它没有正确点亮。我做了一个搜索,发现许多人在点亮3D文本网格时遇到了麻烦,因为它没有任何法线,但我没有找到将法线添加到文本网格对象的解决方案,所以这是我的问题。

如何为文本网格添加法线以使其正确点亮?

非常感谢您的智慧!

1 个答案:

答案 0 :(得分:6)

我为点亮3D纹理做了类似的事情。我希望我的答案不会过分。所以这段代码是我写的一段时间,它效率很低,只支持单个定向灯(有用的cg lighting tuts here)。希望这足以让你开始。

要使用下面的代码创建3D纹理,您需要完成更多工作:

  1. 创建一个空的游戏对象
  2. 附加组件 - >网格 - >文字网格
  3. 附加组件TextMeshNormals(包括在下面)
  4. 附加组件 - >网格 - >网格渲染器
  5. 将材质指定给使用下面的GUI / LitText着色器的网格渲染器
  6. 在着色器中,您会注意到文本普通属性。在实践中,您将使用gameObject的Update()方法更新_Normal属性,其中包含文本所面向的方向,以便它反映方向的更改。文字是平面的,所以我们需要1正常。要测试我手动将法线设置为(0,0,-1,1),因为默认文本网格朝下-Z。

    由于此脚本未在编辑器中运行,因此在预览中运行场景之前,文本不会显示。

    着色器:

    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
        }
    }
    }
    

    帮手脚本:

    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;
        }
    }
    

    <强>更新     Unity 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
        }
    }
    }