Я сделал что-то подобное для освещения 3D-текстуры. Надеюсь, мой ответ не переборщит. Таким образом, этот код был взломом, который я написал некоторое время назад, он неэффективен и поддерживает только один направленный свет (полезно cg lighting tuts here). Надеюсь, этого достаточно, чтобы вы начали.
Для создания 3D-текстуры, используя мой код ниже вы должны пройти немного больше работы:
- Создайте пустой объект игры
- Приложить Component-> Сетка-> Text Mesh
- Attach TextMeshNormals компонент (включены ниже)
- Присоединить Component-> Сетка-> сетка рендерер
- Назначить материал к 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
}
}
}
Я думаю, что нормально зависит при использовании материала и шейдера. Dunno, если это зависит от сеток или нет. Попробуйте изменить шейдер на что-то, что позволяет нормально, например, зеркало – noob
@Creator. Нормаль - это просто ненулевой вектор, который ортогонален к поверхности поли в сетке. Он используется шейдерами для освещения. Шейдеры, которые мне нужно использовать, полагаются на нормали, определяемые для подсвеченной сетки. В этом случае текстовая сетка. Проблема в том, что сетка не имеет никаких нормалей. Таким образом, текст всегда отображается как сплошной белый цвет, независимо от того, в какой среде он находится. – BeachRunnerFred
Есть ли причина, почему вы используете текстовую сетку, а не сетку из 3D-программного обеспечения? Думаю, вы планируете изменить текст во время выполнения? – LightStriker