Hello there, it has been quite a long time since I wrote something on my blog:)
Today I have got a small neat thing to share – simple Flow Map Shader for Unity3D Sprites. To understand what I am talking about just have a look at this gif.
I also have a small repository on GitHub where I study shaders in Unity. This shader can be found there with example of usage.
This kind of shader is usually used with two normal maps to simulate water and was first presented at SIGGRAPH 2010 by Valve. More information about the shader can be fount here. There is a nice tool out there for creating flow maps.
In this case, this is the texture that controls which parts of the image will be moving.
So this is the shader code. I am not good at writing shaders and it can be not very efficient, but it does its job:
Shader "Custom/Flow Map"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
// Flow
_FlowMap ("Flow Map", 2D) = "white" {}
_FlowSpeed ("Flow Speed", float) = 0.05
[MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Cull Off
Lighting Off
ZWrite Off
Blend One OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile _ PIXELSNAP_ON
#include "UnityCG.cginc"
struct appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
half2 texcoord : TEXCOORD0;
};
fixed4 _Color;
v2f vert(appdata_t IN)
{
v2f OUT;
OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
OUT.texcoord = IN.texcoord;
OUT.color = IN.color * _Color;
#ifdef PIXELSNAP_ON
OUT.vertex = UnityPixelSnap (OUT.vertex);
#endif
return OUT;
}
sampler2D _MainTex;
sampler2D _FlowMap;
float _FlowSpeed;
fixed4 frag(v2f IN) : SV_Target
{
float3 flowDir = tex2D(_FlowMap, IN.texcoord) * 2.0f - 1.0f;
flowDir *= _FlowSpeed;
float phase0 = frac(_Time[1] * 0.5f + 0.5f);
float phase1 = frac(_Time[1] * 0.5f + 1.0f);
half3 tex0 = tex2D(_MainTex, IN.texcoord + flowDir.xy * phase0);
half3 tex1 = tex2D(_MainTex, IN.texcoord + flowDir.xy * phase1);
float flowLerp = abs((0.5f - phase0) / 0.5f);
half3 finalColor = lerp(tex0, tex1, flowLerp);
fixed4 c = float4(finalColor, 1.0f) * IN.color;
c.rgb *= c.a;
return c;
}
ENDCG
}
}
}

