2013-04-26 3 views
5

Я использую текст сетки, чтобы поместить текст на 3D объект, но как вы знаете, текст сетка не имеет нормаль ...Как добавить нормальную к текстовой сетке так, чтобы она правильно светилась?

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

... так что это не правильно светится. Я выполнил поиск и обнаружил, что у многих людей возникают проблемы с освещением 3D-сетки из-за того, что у него нет никаких нормалей, но я не нашел решения по добавлению нормалей в текстовый объект-меш, так что это мой вопрос.

Как добавить нормальное значение в текстовую сетку, чтобы оно правильно светилось?

Большое спасибо за вашу мудрость!

+0

Я думаю, что нормально зависит при использовании материала и шейдера. Dunno, если это зависит от сеток или нет. Попробуйте изменить шейдер на что-то, что позволяет нормально, например, зеркало – noob

+0

@Creator. Нормаль - это просто ненулевой вектор, который ортогонален к поверхности поли в сетке. Он используется шейдерами для освещения. Шейдеры, которые мне нужно использовать, полагаются на нормали, определяемые для подсвеченной сетки. В этом случае текстовая сетка. Проблема в том, что сетка не имеет никаких нормалей. Таким образом, текст всегда отображается как сплошной белый цвет, независимо от того, в какой среде он находится. – BeachRunnerFred

+0

Есть ли причина, почему вы используете текстовую сетку, а не сетку из 3D-программного обеспечения? Думаю, вы планируете изменить текст во время выполнения? – LightStriker

ответ

6

Я сделал что-то подобное для освещения 3D-текстуры. Надеюсь, мой ответ не переборщит. Таким образом, этот код был взломом, который я написал некоторое время назад, он неэффективен и поддерживает только один направленный свет (полезно cg lighting tuts here). Надеюсь, этого достаточно, чтобы вы начали.

Для создания 3D-текстуры, используя мой код ниже вы должны пройти немного больше работы:

  1. Создайте пустой объект игры
  2. Приложить Component-> Сетка-> Text Mesh
  3. Attach TextMeshNormals компонент (включены ниже)
  4. Присоединить Component-> Сетка-> сетка рендерер
  5. Назначить материал к Mesh Renderer, который использует свой GUI/LitText шейдер ниже

В шейдере вы увидите текст нормального атрибута. На практике у вас будет метод Update() вашего gameObject обновить свойство _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; 
    } 
} 

Update 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 
    } 
} 
} 
+0

+1: хорошее решение. Нужно ли отключать компонент TextMesh? Поскольку кажется, что теперь TextMeshNormals отвечает за визуализацию текста. – Heisenbug

+0

@Heisenbug Хорошая идея, я не думал проверять. Посмотрев на код, я не уверен, что TextMesh можно отключить. Кажется, это чистый компонент без элемента 'enabled'. – Jerdak

+0

Спасибо, @Jerdak, это очень полезно! Я сделаю это. – BeachRunnerFred

 Смежные вопросы

  • Нет связанных вопросов^_^