﻿//Original shader is https://www.shadertoy.com/view/ltffzl
Shader "Custom/Surface Rain" {
	Properties 
	{
		_Glossiness ("Smoothness", Range(0,1)) = 0.5
		_Metallic ("Metallic", Range(0,1)) = 0.0
		[Toggle]LR("Light Reaction", int) = 0
		[Toggle]PP("Post Processing", int) = 0
		_rainint("Rain intensity", range(0,1)) = 0.7
		_rainamount("Rain amount", range(0,1)) = 0.1
		_x("Resize X", float) = 1
		_y("Resize Y", float) = 1
		_ds("Blur", Range(0,1)) = 0.5
		_dis("Distortion", range(0,1)) = 1
		[HideInInspector] _texcoord( "", 2D ) = "white" {}
	}
	SubShader 
	{
			Tags { "RenderType"="Transparent" "Queue"="Overlay"}
			GrabPass {"_Grab"}
			LOD 200
			CGPROGRAM
			#pragma surface surf Standard fullforwardshadows vertex:vertexFunc 
			#pragma target 4.0
			#pragma shader_feature PP_ON
			#pragma shader_feature LR_ON

			half _Glossiness;
			half _Metallic;
			sampler2D _Grab;
			float _rainint;
			float _rainamount;
			float _ds;
			float _x;
			float _y;
			float _dis;

			struct Input 
			{
				float4 gp;
				float2 uv_texcoord;
			};

			void vertexFunc( inout appdata_full v, out Input o )
			{
				UNITY_INITIALIZE_OUTPUT( Input, o );
				float4 vertexPos = v.vertex;
				o.gp = ComputeGrabScreenPos(UnityObjectToClipPos(vertexPos));
			}

			float3 N13(float p) 
			{
   				float3 p3 = frac(float3(p,p,p) * float3(0.1031,0.11369,0.13787));
   				p3 += dot(p3, p3.yzx + 19.19);
   				return frac(float3((p3.x + p3.y)*p3.z, (p3.x+p3.z)*p3.y, (p3.y+p3.z)*p3.x));
			}

			float4 N14(float t) 
			{
				return frac(sin(t*float4(123.0, 1024.0, 1456.0, 264.0))*float4(6547.0, 345.0, 8799.0, 1564.0));
			}

			float N(float t) 
			{
    			return frac(sin(t*12345.564)*7658.76);
			}

			float Saw(float b, float t) 
			{
				return smoothstep(0.0, b, t)*smoothstep(1.0, b, t);
			}

			float2 DropLayer2(float2 uv, float t) 
			{
    			float2 UV = uv;
    			uv.y += t*0.75;
    			float2 a = float2(6.0, 1.0);
    			float2 grid = a*2.0;
    			float2 id = floor(uv*grid);
    
    			float colShift = N(id.x); 
    			uv.y += colShift;
    
    			id = floor(uv*grid);
    			float3 n = N13(id.x*35.2+id.y*2376.1);
    			float2 st = frac(uv*grid)-float2(0.5, 0.0);
    
    			float x = n.x-0.5;
    
    			float y = UV.y*20.0;
    			float wiggle = sin(y+sin(y));
    			x += wiggle*(.5-abs(x))*(n.z-0.5);
    			x *= 0.7;
    			float ti = frac(t+n.z);
    			y = (Saw(0.85, ti)-0.5)*0.9+0.5;
    			float2 p = float2(x, y);
    
    			float d = length((st-p)*a.yx);
    
    			float mainDrop = smoothstep(0.4, 0.0, d);
    
    			float r = sqrt(smoothstep(1.0, y, st.y));
    			float cd = abs(st.x-x);
    			float trail = smoothstep(0.23*r, 0.15*r*r, cd);
    			float trailFront = smoothstep(-0.02, 0.02, st.y-y);
    			trail *= trailFront*r*r;
    
    			y = UV.y;
    			float trail2 = smoothstep(0.2*r, 0.0, cd);
    			float droplets = max(0., (sin(y*(1.0-y)*120.0)-st.y))*trail2*trailFront*n.z;
    			y = frac(y*10.0)+(st.y-0.5);
    			float dd = length(st-float2(x, y));
    			droplets = smoothstep(0.3, 0.0, dd);
    			float m = mainDrop+droplets*r*trailFront;

    			return float2(m, trail);
			}

			float StaticDrops(float2 uv, float t) 
			{
				uv *= 40.0;
    
    			float2 id = floor(uv);
    			uv = frac(uv)-0.5;
    			float3 n = N13(id.x*107.45+id.y*3543.654);
    			float2 p = (n.xy-0.5)*0.7;
    			float d = length(uv-p);
    
    			float fade = Saw(0.025, frac(t+n.z));
    			float c = smoothstep(0.3, 0.0, d)*frac(n.z*10.0)*fade;
    			return c;
			}

			float2 Drops(float2 uv, float t, float l0, float l1, float l2) 
			{
    			float s = StaticDrops(uv, t)*l0; 
    			float2 m1 = DropLayer2(uv, t)*l1;
    			float2 m2 = DropLayer2(uv*1.85, t)*l2;
    
    			float c = s+m1.x+m2.x;
    			c = smoothstep(.3, 1., c);
    
    			return float2(c, max(m1.y*l0, m2.y*l1));
			}

			float N21 (float2 uv)
			{
				uv = frac(uv*float2(123.34, 345.56));
				uv += dot(uv, uv + 34.456);
				return frac(uv.x*uv.y);
			}

			void surf (Input i, inout SurfaceOutputStandard o) 
			{
				float2 uv = i.uv_texcoord*(1.0+_rainamount*10.0);

				uv.x *= _x;
				uv.y *= _y;

    			float2 UV = i.gp.xy/i.gp.w;

    			float T = _Time.y;
    			float t = T*0.2;
    
    			float rainAmount = sin(T*0.05*_rainint)*0.3*_rainint+_rainint*2.0;
    
    			float staticDrops = smoothstep(-0.5, 1.0, rainAmount)*2.0;
    			float layer1 = smoothstep(0.25, 0.75, rainAmount);
    			float layer2 = smoothstep(0.0, 0.5, rainAmount);

    			float maxBlur = lerp(3., 6., rainAmount);
    			float minBlur = 2.;

    			float2 c = Drops(uv, t, staticDrops, layer1, layer2);
    			float2 e = float2(0.001, 0.0);
    			float cx = Drops(uv+e, t, staticDrops, layer1, layer2).x;
    			float cy = Drops(uv+e.yx, t, staticDrops, layer1, layer2).x;
    			float2 n = float2(cx-c.x, cy-c.x);
    			float fwd = saturate(1-fwidth(i.uv_texcoord)*50);
    			UV += n * _dis * fwd;

    			float blur = length(float2(0.3 * 0.07 * (1 - c.x), 0.5 * 0.07 * (1 - c.y)));
				float a = N21(i.uv_texcoord)*(UNITY_PI)*2;
				float4 col = 0;

				for (float i = 0; i < 16; i++)
				{
					float2 offs = float2(sin(a), cos(a)) * blur * _ds * fwd;
					#if UNITY_SINGLE_PASS_STEREO
					offs.x *= (_ScreenParams.y/_ScreenParams.x) * 0.5;
					float d = sqrt(frac(sin((i + 1) * 545) * 5426));// 524 5247.65
					#else
					offs.x *= _ScreenParams.y/_ScreenParams.x;
					float d = sqrt(frac(sin((i + 1) * 546) * 5424));// 524 5247.65
					#endif
					offs *= d;
					col += tex2D(_Grab, UV + offs);
					a++;
				}
				col /= 16;

				#ifdef PP_ON
    			t = (_Time.y+3.0)*0.5;
    			float colFade = sin(t*0.2)*0.5+0.5;
    			col *= lerp(float4(1.0, 1.0, 1.0, 1.0), float4(0.8, 0.9, 1.3, 1.0), colFade);
    			float f = smoothstep(0.0, 10.0, _Time.y);
    			float lightning = sin(t*sin(t*10.0));
    			lightning *= pow(max(0.0, sin(t+sin(t))), 10.0);
    			col *= 1.0+lightning*f*lerp(1.0, 0.1, 0.0);
    			col *= f;
    			#endif
    			//col *= 0; col = focus;
    			#ifdef LR_ON
				o.Emission = 0;
				o.Albedo = col.rgb;
				#else
				o.Emission = col.rgb;
				o.Albedo = 0;
				#endif
				o.Metallic = _Metallic;
				o.Smoothness = _Glossiness;
				o.Alpha = col.a;
			}
		ENDCG
	}
	FallBack "Diffuse"
}