﻿//Original shader is https://www.shadertoy.com/view/ltffzl
//v1.1
Shader "Doppels shaders/World/Unlit Rain by BigWings (configurated for vrchat)" {
	Properties
	{
		[Header (UV Settings)]
		[Space]
		_rotateuv("Rotate UV", range(-100, 100)) = 0.0
		_x("Resize X", float) = 5
		_y("Resize Y", float) = 5
		[Header (Rain Settings)]
		[Space]
		[Toggle]postpr("Post Processing", int) = 0
		_rainint("Rain Intensity", range(0,1)) = 1.0
		_ds("Blur", Range(0,1)) = 0.4
		_dis("Distortion", range(0,1)) = 0.3
	}
	SubShader
	{
		Tags { "RenderType"="Transparent" "Queue"="Transparent" }
		LOD 100
		GrabPass {"_Grab"}
		Pass
		{
			CGPROGRAM
			#pragma target 4.0
			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc"

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

			struct v2f
			{
				float4 vertex : SV_POSITION;
				float2 uv : TEXCOORD0;
				float4 gp : TEXCOORD1;
			};

			uniform sampler2D _Grab;
			uniform float _rainint, _rotateuv, _ds, _x, _y, _dis;
			uniform int postpr;
			
			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = v.uv;
				o.gp = ComputeGrabScreenPos(o.vertex);
				return o;
			}

			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);
			}

			float2x2 rot(float p)
			{
			    return float2x2(cos(p),-sin(p),sin(p),cos(p));
			}

			fixed4 frag (v2f i) : SV_Target
			{
				float2 uv = i.uv;

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

				uv = mul(uv, rot(_rotateuv*0.01*UNITY_TWO_PI));

    			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 dstf = saturate(pow(1 - fwidth(i.uv)*1.5, 60.0));
    			UV += n * _dis * dstf;
    			c *= dstf;
    			float blur = (1 - c.x * _dis) * saturate(1 - c.y * 2 * _dis) * dstf;
				float a = N21(i.uv) * (UNITY_TWO_PI);
				float4 col = 0;

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

				UNITY_BRANCH if (postpr != 0)
				{
    				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;
    			}

    			return col;
			}
			ENDCG
		}
	}
}
