Tutorial on how we made this really simple water reflection effect
Some people have asked how we did a reflection effect in our game. So I decided to post a code and a small tutorial for that, because it is really simple and may help someone who is just starting with game development and give them a tool to use in their 2d games.
So we are making this reflection effect.
If you want to see it in dynamics, here is a link to our game.

1) At first you need a shader file. You can create it via Unity or simply create a text file somewhere inside your assets folder, call it "Water" (or whatever you want) and make its extension ".shader".
2) Then paste all this code there:
```
// You can change the name to whatever you like. Shader "DashingAshes/Water" { Properties { _MainTex ("Texture", 2D) = "white" {} _FoamColor ("FoamColor", Color) = (0.8235295, 0.8470589, 0.8588236, 1) _ThickFoamSize ("ThickFoamSize", Float) = 0.03125 _WaterLevel ("WaterLevel (WorldY)", Float) = -0.325 } SubShader { Tags{"Queue" = "Transparent+10"} // No culling or depth Cull Off ZWrite Off ZTest Always
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata {
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f {
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert (appdata v) {
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
sampler2D _MainTex;
fixed4 _FoamColor;
float _ThickFoamSize;
float _WaterLevel;
// Here is a reflection code.
fixed4 frag (v2f i) : SV_Target {
fixed4 col = fixed4(0,0,0,0);
float doubleOrtho = (2 * unity_OrthoParams.y);
// We are calculating, where on our screen would be the water level.
// Screen coords go from 0 to 1. So 0.5 is a middle and we are counting from the middle.
float waterLevelInScreenSpace = 0.5 + (_WaterLevel - _WorldSpaceCameraPos.y)/ doubleOrtho;
// i.uv.y - is our screen coord and if it is below our screen space water level, then
// we are drawing the water fragment.
if (i.uv.y < waterLevelInScreenSpace) {
float2 uv = i.uv;
uv.y = 2 * waterLevelInScreenSpace - i.uv.y;
col = tex2D(_MainTex, uv);
// We linearly interpolate our color from
// _FoamColor(wich is the color on top of our water)
// to the color of reflection.
// Play around with this line. Especially the last 0.25 parameter.
col = lerp(_FoamColor, col, 0.75 + clamp(5*(waterLevelInScreenSpace - i.uv.y), 0, 0.25));
// This detects if we are drawing the most upper level of water.
if (i.uv.y > waterLevelInScreenSpace - _ThickFoamSize/doubleOrtho) {
// And if so, then we are painting it with a little more intensive _FoamColor.
// Play around with this as well.
col = col * 0.75 + 0.25*_FoamColor;
}
}
// If our screen coord is above screen space water level, then we are drawing the regular
// world fragment and not water.
else {
col = tex2D(_MainTex, i.uv);
}
return col;
}
ENDCG
}
}
}
```
3) Now create new material and set it to use this shader.

4) And then you have to create a new script from which we will be calling a post-processing render with our material. Create new script, name it "ImageEffect" and replace all its contents with this:
```
using UnityEngine; using System.Collections;
[ExecuteInEditMode] public class ImageEffect : MonoBehaviour { public Material material;
// Postprocess the image
void OnRenderImage (RenderTexture source, RenderTexture destination) {
Graphics.Blit (source, destination, material);
}
}
```
5) The script is ready, now you have to add it to your camera. DO NOT FORGET TO MAKE IT ORTHOGRAPHIC! After adding just link your water material (not shader) to the "Material" input.

6) Now you are all set and just need to configure the material parameters to your likings.

Some thoughts and further work
- This effect works in your screenspace, so if you put your camera too low or your water level too high there will be a problem, so its only good if your water occupies less then half of the screen.
- You can work with the color mixing in shader to achieve the desired look.
- I wanted to make it myself during the jam but had no time left. You can add some dynamic distortions (waves) to the reflection so it will be more like water and less like mirror.