利用正弦曲线实现平滑的起伏效果:
1. 时间是稳步增加的数值,如果给时间节点加上顶点的位置信息,同一时间不同位置的数据就有了差异性,将时间加上位置偏移量作为sin操作的数据输入,就得到了一串与位置相关的具有差异的正弦运算结果值
2. 将1)中得到的数据作为顶点坐标的y方向上的增量,go就具有了平滑起伏波动的飘动效果
3. 要固定旗帜的一端,就要让一侧的波动值置0,在向另一端方向上波动程度不断增大,我们直接给offset值乘以uv的u值即可(uv至是从(0,0)到(1,1)不断增大的二维数组,那么u值就是从0到1稳步增大的一维数组)
正弦曲线
y=Asin(ωx+φ)+k
- y= sinx在[0,2π]周期的曲线图
- 振幅
A- 频率
波长的倒数- 波长
2π/ω
Shader "Unlit/flag_us"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_FlagColor("flag color", Color) = (1, 0, 0, 1)
_Frequency("frequency", float) = 1
_Strength("amplitude strength", float) = 1
_WaveLength("wave length", float) = 1
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _FlagColor;
float _Frequency;
float _Strength;
float _WaveLength;
v2f vert (appdata v)
{
v2f o;
o.uv = v.uv;
// 计算偏移之前的顶点位置
float4 v_before = mul(unity_ObjectToWorld,v.vertex);
// 为时间加上顶点位置的x+z*0.6(0.6是自己喜欢的系数,可以自行调节效果修改)作为sin的输入,乘以系数之后将最后的结果作为顶点偏移值
v.vertex.xyz += _Strength*float3(0, sin(_Time.y*_Frequency +(v_before.r + v_before.b*0.6)*_WaveLength)*o.uv.r, 0);
o.vertex = UnityObjectToClipPos(v.vertex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = fixed4(_FlagColor.rgb, 1);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}
作为sin输入数据的是时间加偏移值,这个偏移值这里选取的是世界位置坐标信息,此外还可以是uv信息等等,只要是连续的有差异的数据都可以。
Unity 3d可视化节点材质Shader Forge实用教程 初级进阶篇
在旗帜飘动原理的基础上,我们可以实现很多类似的效果,比如草丛晃动,衣带头发的飘动,水面波浪等等
例如:
=>
Shader Forge 植物摆动
unity shader 人物走入草丛,草的晃动特效特效怎么做?
Unity3D手游开发日记(9) - 互动草的效果
shader水面起伏的波浪