﻿Shader "PleasureArcade/DripShader"
{
    Properties
    {
		_MainTex("Drip Map", 2D) = "white" {}
		_Cylinder("Cylinder Map", 2D) = "white" {}
		_DepthAdjust ("Depth Adjust", Float) = 0
		_Width ("Width", Float) = 1
		_FakeTime ("Time", Range(0,1)) = 0

		[Toggle(SOFT_PARTICLES)] _SoftParticles("Soft", Int) = 0
		_SoftParticleFade ("Soft Fade", Float) = 0.25

		_StencilLayer ("Stencil Layer", Int) = 69
    }
    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent+11" "VRCFallback"="Hidden"}
        LOD 100

        Pass
        {
			Blend OneMinusDstColor One
            Cull Off Lighting Off ZWrite Off
            ColorMask A
			ZTest Always

			Stencil
            {
                Ref [_StencilLayer]
                Comp Always
                Pass Replace
            }

            CGPROGRAM

            #pragma vertex vert
            #pragma fragment frag
			#pragma shader_feature SOFT_PARTICLES

            #include "UnityCG.cginc"

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

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

            sampler2D _MainTex;
			sampler2D _Cylinder;
            float4 _MainTex_ST;

			// built-in
			sampler2D _CameraDepthTexture;
			half4 _CameraDepthTexture_ST;

			float _DepthAdjust;
			float _SoftParticleFade;
			float _Width;
			float _FakeTime;

			v2f vert (appdata v)
            {
				v2f o;
				o.uv = v.uv;
				// Find object space scaling factor i.e. length of object-unit vector in world-space
				float scaleFactor = length(mul(unity_ObjectToWorld, float3(1, 0, 0)));
				// Horizontal billboard
				o.vertex = mul(UNITY_MATRIX_P, mul(UNITY_MATRIX_MV, v.vertex) + float4(mad(v.uv.x, 2, -1) * _Width * scaleFactor, 0, 0, 0));
				// Override cameraSpace.z with depth
				o.cameraSpace = ComputeGrabScreenPos(o.vertex);
				o.cameraSpace.z = UnityObjectToViewPos(v.vertex).z * _ProjectionParams.w * -1.;
                return o;
            }

			bool IsMirrorClone()
			{
				return unity_CameraProjection[2][0] != 0.f || unity_CameraProjection[2][1] != 0.f;
			}

            fixed4 frag (v2f i) : SV_Target
            {
				clip(IsMirrorClone() ? -1 : 1);
				
				float col = tex2D(_MainTex, float2(_FakeTime, i.uv.y)).r * tex2D(_Cylinder, float2(i.uv.x, 0)).r;

				// Trim out square edges
				clip(col - 0.001);

				// screen space UVs: _ProjectionParams.x = -1 if projection is flipped (DirectX render)
				float2 ssUV = i.cameraSpace.xy/i.cameraSpace.w;
				ssUV.y = -1 * ssUV.y * _ProjectionParams.x + step(0, _ProjectionParams.x);
				ssUV = UnityStereoScreenSpaceUVAdjust(ssUV, _CameraDepthTexture_ST);
				float bufferDepth = Linear01Depth(tex2D(_CameraDepthTexture, ssUV)).r - _DepthAdjust * _ProjectionParams.w;

				#ifndef SOFT_PARTICLES
				clip(bufferDepth - i.cameraSpace.z);
				#endif

				#ifdef SOFT_PARTICLES
                // sample the texture
				col *= smoothstep(0, _ProjectionParams.w * _SoftParticleFade, bufferDepth - i.cameraSpace.z);
				#endif

                return fixed4(col, col, col, col);
            }
            ENDCG
        }
    }
}
