亚历山大和鲈鱼
本节使用shader模拟蝴蝶扇动翅膀和鱼游动的动画。
原理
属于简单又好用的shader。还是vertex displacement。
蝴蝶的模型就是一张plane,简单根据贴图处理一下就行——
ps: 网上找的鱼模型,鱼的尾巴和鳍分离了,这告诉我们这个shader适用于完整接连的mesh模型
使用时注意旋转方向,blender导出的模型一般会在某个轴旋转90度,如果效果不对自己调一下。
蝴蝶Shader
Shader "Lapu/ButterflyShader"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
_AlphaCutoff("Alpha cutoff", Range(0, 1)) = 0
_DisplacementAmount("Displacement Amount", float) = 1
_DisplacementSpeed("Displacement Speed", float) = 1
}
SubShader
{
Tags { "RenderType" = "Opaque" }
LOD 100
Cull off
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;
float _AlphaCutoff;
float _DisplacementAmount;
float _DisplacementSpeed;
v2f vert(appdata v)
{
v2f o;
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
float mask = 1 - sin(UNITY_PI * o.uv.x);
v.vertex.z += sin(_Time.y * _DisplacementSpeed) * _DisplacementAmount * mask;
o.vertex = UnityObjectToClipPos(v.vertex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
clip(col.a - _AlphaCutoff);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}
鱼shader
Shader "Lapu/FishShader"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
_TranslationAmount("Translation amount", float) = 1
_DisplacementAmount("Displacement amount", float) = 1
_DisplacementSpeed("Displacement speed", float) = 1
_MaskOffset("Mask offset", Range(0, 1)) = 0
}
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;
float _MaskOffset;
float _TranslationAmount;
float _DisplacementAmount;
float _DisplacementSpeed;
v2f vert(appdata v)
{
v2f o;
float mask = saturate(sin((v.uv.x + _MaskOffset) * UNITY_PI));
v.vertex.x += sin(_Time.y * _DisplacementSpeed) * _TranslationAmount;
v.vertex.x += sin(v.uv.x * UNITY_PI + _Time.y * _DisplacementSpeed) * _DisplacementAmount * mask;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}