Shader "Unlit/WaveShader"
{
	Properties
	{
        _Tess ("Edge length", Range(1,32)) = 4
		_Color ("Color", Color) = (1,1,1,1)
		_ShadowColor ("Shadow Color", Color) = (1,1,1,1)
		_WaveColor ("Wave Color", Color) = (1,1,1,1)
	}
	SubShader
	{
		Tags { "RenderType"="Opaque" }
		LOD 100

		Pass
		{
			CGPROGRAM
			#pragma vertex vert tessellate tessDistance nolightmap
			#pragma fragment frag
			// make fog work
			#pragma multi_compile_fog
			#pragma target 4.6
            #include "Tessellation.cginc"
			
			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			}; 

			float _Tess;

            float4 tessDistance (appdata v0, appdata v1, appdata v2) 
            {
                float minDist = 10.0;
                float maxDist = 25.0;
                return UnityDistanceBasedTess(v0.vertex, v1.vertex, v2.vertex, minDist, maxDist, _Tess);
            }

			struct v2f
			{
				float2 uv : TEXCOORD0;
				UNITY_FOG_COORDS(1)
				float4 vertex : SV_POSITION;
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;
			fixed4 _Color;
			fixed4 _ShadowColor;
			fixed4 _WaveColor;
			float _WaveWidth;
			float _FadePow;
			float _SizePow;
			half4 _ShadowPoints[4];
			half4 _Waves[16];

			
			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = v.uv;
				UNITY_TRANSFER_FOG(o,o.vertex);
				return o;
			}
			
			fixed4 frag (v2f IN) : SV_Target
			{
				fixed4 col;
            	const float PI = 3.14159;

				// Shadows
				float shadowStrength = 0;
				for(int i = 0; i<_ShadowPoints.Length; i++)
				{
					float distFromShadow = length(float2(_ShadowPoints[i].xy - IN.uv));
					shadowStrength = max(shadowStrength, smoothstep(distFromShadow, distFromShadow+0.0025, _ShadowPoints[i].z));
				}
				col = lerp(_Color, _ShadowColor, shadowStrength);

				// Waves
				float waveStrength = 0;
				for(int i = 0; i<_Waves.Length; i++)
				{
					float distFromWave = length(float2(_Waves[i].xy - IN.uv));
					float steppedWave = smoothstep(distFromWave, distFromWave+_WaveWidth, 1.0-(pow(1.0-_Waves[i].z, _SizePow)));

					float shapedWave = 0.5*(sin((steppedWave*2.0*PI - 0.5*PI))+1.0);
					waveStrength = max(waveStrength, shapedWave*_Waves[i].w*max(1.0-pow(_Waves[i].z, _FadePow), 0.0));
				}

				col = lerp(col, _WaveColor, waveStrength);

				// apply fog
				UNITY_APPLY_FOG(IN.fogCoord, col);
				return col;
			}
			ENDCG
		}
	}
}
