模型资源出自《Shader入门精要》的项目,github链接如下:
原理:利用顶点动画,sin函数,纹理坐标,网格顶点坐标实现的旗帜漂浮效果
物体是Quad(3D物体)
注意:这个物体的模型是自定义的,不是默认的!(这个模型资源在上方的链接项目内)
可看到有164个顶点(这种才能实现我的效果!)而Quad物体默认的模型,如下:
只有4个verts(4个顶点)!这种是无法实现我下面的效果的。(因为顶点才4个!怎么模拟顶点动画!)
(如果发现方向不对!请自行旋转或调整shader的偏移轴等等轴向问题!)
Shader可以说十分简单,如下:
//必须要有一个多顶点的网格面支持才能很好地形成旗帜动画!
Shader "Unlit/FlagFlowing"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
//颜色
_FlagColor("flag color", Color) = (1, 0, 0, 1)
//频率
_FrequencyY("frequency Y", float) = 1
//飘动幅度
_StrengthY("amplitude strengthY", float) = 1
//波长
_WaveLengthY("wave length Y", 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 _FrequencyY;
float _StrengthY;
float _WaveLengthY;
v2f vert(appdata v)
{
v2f o;
o.uv = v.uv;
//关键代码:顶点动画部分
//计算出偏移值y,对模型顶点的y值进行偏移
//偏移值y的计算是根据sin函数,_FrequencyY系数控制频率,v.vertex.z是模型网格的Z轴(变化较大的轴)利用它的差异性来让sin值呈现平滑的曲线差异性
//最终sin值要乘以一个纹理坐标y值进行模拟旗帜一边不动,一边浮动的效果
//PS:差异性是指同一时间,不同顶点位置的偏移有差别的意思, 这样才能有漂浮效果.
float y = sin(_Time.y * _FrequencyY + (v.vertex.x + v.vertex.z * 0.6) * _WaveLengthY) * o.uv.y;
float4 offset = float4(0, 0, 0, 0);
offset.y = y * _StrengthY;
o.vertex = UnityObjectToClipPos(v.vertex + offset);
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
}
}
}