最近需要波浪形态的文字(水人震怒)
大概就是海面那样上下(左右)摇摆
做了两个 都可以改变摆动速率
一开始用shader来做
结合了这个 和 这个做了一个
Shader "Custom/textWave" {
Properties{
_MainTex("Font Texture", 2D) = "white" {}
_Color("Text Color", Color) = (1,1,1,1)
_OutlineColor("Outline Color", Color) = (0,0,0,1)
_StencilComp("Stencil Comparison", Float) = 3.000000
_Stencil("Stencil ID", Float) = 1.000000
_StencilOp("Stencil Operation", Float) = 0.000000
_StencilWriteMask("Stencil Write Mask", Float) = 0.000000
_StencilReadMask("Stencil Read Mask", Float) = 1.000000
_Amplitude ("振幅(最大和最小的幅度)", Range(0, 1)) = 0.3
_AngularVelocity ("角速度(圈数)", Range(0, 50)) = 10
_Speed ("移动速度", Range(0, 30)) = 10
}
SubShader{
Tags {
"Queue" = "Transparent"
"IgnoreProjector" = "True"
"RenderType" = "Transparent"
"PreviewType" = "Plane"
}
Lighting Off Cull Off ZTest Always ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Stencil {
Ref[_Stencil]
ReadMask[_StencilReadMask]
WriteMask[_StencilWriteMask]
Comp[_StencilComp]
Pass[_StencilOp]
}
//ColorMask[_ColorMask]
//第一个Pass,实现Text内容背景颜色,并向外扩大_OutlineWidth
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile _ UNITY_SINGLE_PASS_STEREO STEREO_INSTANCING_ON STEREO_MULTIVIEW_ON
#include "UnityCG.cginc"
struct appdata_t {
float4 vertex : POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
//UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f {
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_OUTPUT_STEREO
};
sampler2D _MainTex;
uniform float4 _MainTex_ST;
uniform float4 _MainTex_TexelSize;
uniform fixed4 _Color;
uniform fixed4 _OutlineColor;
v2f vert(appdata_t v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.vertex = UnityObjectToClipPos(v.vertex);
o.color = v.color;
o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex);
return o;
}
//确定每个像素周围8个像素的坐标。
static const float2 dirList[9] = {
float2(-1,-1),float2(0,-1),float2(1,-1),
float2(-1,0),float2(0,0),float2(1,0),
float2(-1,1),float2(0,1),float2(1,1)
};
//谋取dirList第dirIndex个方位的透明度值。
float getDirPosAlpha(float index, float2 xy) {
float2 curPos = xy;
float2 dir = dirList[index];
float2 dirPos = curPos + dir * _MainTex_TexelSize.xy *0;
return tex2D(_MainTex, dirPos).a;
};
//对于每个像素,传入片元参数v2f i ,获取次像素周围和自身的共9个像素进行透明度叠加。
//那么得出的结果就是非透明的区域被放大了,形成了黑边。
float getShadowAlpha(float2 xy) {
float a = 0;
float index = 0;
a += getDirPosAlpha(index, xy);
// a += getDirPosAlpha(index++, xy);
// a += getDirPosAlpha(index++, xy);
// a += getDirPosAlpha(index++, xy);
// a += getDirPosAlpha(index++, xy);
// a += getDirPosAlpha(index++, xy);
// a += getDirPosAlpha(index++, xy);
// a += getDirPosAlpha(index++, xy);
// a += getDirPosAlpha(index++, xy);
a = clamp(a,0,1);
return a;
}
float _Amplitude;
float _AngularVelocity;
float _Speed;
//由于渲染Text内容时,Text字上没有被渲染的区域是透明的,也就是透明度a值是0,
//所以只要将有内容的区域往外透明度为0的区域扩展一些像素将就能够形成描边效果。
fixed4 frag(v2f i) : SV_Target
{
i.texcoord.y += (_Amplitude * sin(_AngularVelocity * i.texcoord.x + _Speed * _Time.y));
fixed4 col = i.color;//_OutlineColor;
float2 xy = i.texcoord.xy;
col.a *= getShadowAlpha(xy);
return col;
}
ENDCG
}
}
}
没有把这段简化 清理是因为不是很好用 而且有瑕疵 会取到字体的额外材质
希望有大神能想到怎么用shader达成完美目标
总之 在学习油管之后
写了个比较好的 需要用textMeshPro 反正是免费的 不用白不用
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class textWaveMesh : MonoBehaviour
{
public TMP_Text tmpText;
public Mesh mesh;
public Vector3[] myVecs;
void Update()
{
tmpText.ForceMeshUpdate();
mesh=tmpText.mesh;
myVecs=mesh.vertices;
for (int i = 0; i < tmpText.textInfo.characterCount; i++)
{
TMP_CharacterInfo c = tmpText.textInfo.characterInfo[i];
int index = c.vertexIndex;
Vector3 offset = Wobble(Time.time + i);
myVecs[index] += offset;
myVecs[index + 1] += offset;
myVecs[index + 2] += offset;
myVecs[index + 3] += offset;
}
mesh.vertices = myVecs;
tmpText.canvasRenderer.SetMesh(mesh);
}
Vector2 Wobble(float time) {
return new Vector2(Mathf.Sin(time*3.3f), 5*Mathf.Cos(time*2.5f));
}
}
需要改变波浪的形态的
改wobble里面的Mathf.Sin(time3.3f), 5Mathf.Cos(time*2.5f)
前面是x后面是y 不多解释了
最后效果