It has been made with Unity 5.4.2f1 and has been tested on PC and mobile. But I don’t guarantee crazy performances or compatibility everywhere.

How it works

1/ Transparent bumped colored shader

a GrabPass, so it can display everything that has been drawn before

a Color to apply to the grabbed texture

bump mapping

an additional sinusoïdal deformation with the magnitude parameter

So it’s a simple transparent shader that applies a color and a light deformation, yep.

2/ Reflection

The reflection is just a simple trick. For every object we want to reflect in the water, we create a new mirroded sprite!

The WaterReflectableScript will do it automagically. Simply add it to a sprite that should be reflected and, on runtime, a mirroded sprite will appear.

And that’s it!

The shader

As I say, I am not skilled in shader creation.

Please feel free to contribute and to correct all my mistakes, I’m sure this could be optimized.

Shader"Custom/Water2D Surface"{Properties{_Color("Color",Color)=(1,1,1,1)_MainTex("Normalmap",2D)="bump"{}_Magnitude("Magnitude",Range(0,1))=0.05}Category{Tags{"Queue"="Transparent"}SubShader{// This pass grabs the screen behind the object into a texture.
// We can access the result in the next pass as _BackgroundTex
GrabPass{"_BackgroundTex"}// Main pass: Take the texture grabbed above and use the bumpmap to perturb it
// on to the screen
Pass{Name"BASE"CGPROGRAM#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
structvertexInput{float4vertex:POSITION;float2texcoord:TEXCOORD0;};structvertexOutput{float4vertex:SV_POSITION;float4uvgrab:TEXCOORD0;float2uvmain:TEXCOORD2;UNITY_FOG_COORDS(3)};fixed4_Color;sampler2D_MainTex;float4_MainTex_ST;float_BumpAmt;float4_BumpMap_ST;float_Magnitude;vertexOutputvert(vertexInputv){vertexOutputo;o.vertex=mul(UNITY_MATRIX_MVP,v.vertex);#if UNITY_UV_STARTS_AT_TOP
floatscale=-1.0;#else
floatscale=1.0;#endif
o.uvgrab.xy=(float2(o.vertex.x,o.vertex.y*scale)+o.vertex.w)*0.5;o.uvgrab.zw=o.vertex.zw;o.uvmain=TRANSFORM_TEX(v.texcoord,_MainTex);UNITY_TRANSFER_FOG(o,o.vertex);returno;}sampler2D_BackgroundTex;float4_GrabTexture_TexelSize;sampler2D_BumpMap;half4frag(vertexOutputi):SV_Target{// Calculate perturbed coordinates
half4bump=tex2D(_MainTex,i.uvmain);half2distortion=UnpackNormal(bump).rg;i.uvgrab.xy+=distortion*_Magnitude;// Get pixel in GrabTexture, rendered in previous pass
half4col=tex2Dproj(_BackgroundTex,UNITY_PROJ_COORD(i.uvgrab));// Apply color
col*=_Color;returncol;}ENDCG}}}}

Credits

Thanks to Branden for the height map and inspiration. Check out his article for a similar solution with more details on the shaders.