shader "URP/Environment/Grass/GrassPlayerInteractive"{
	Properties{
		//for satisfy srp shader property requirement
		[HideInInSpector]_MaskTex("Interactive Mask (RGB)", 2D) = "white" {}
		[HideInInSpector]_InteractiveTex("Interactive (RGB)", 2D) = "white" {}
		[HideInInSpector]_InteractiveTex_TexelSize("", Vector) = (0, 0, 0, 0)
		[HideInInSpector]_MaskTex_TexelSize("", Vector) = (0, 0, 0, 0)
		[HideInInSpector]_Dif("", Vector) = (0, 0, 0, 0)
		[HideInInSpector]_CenterPos("", Vector) = (0, 0, 0, 0)
		[HideInInSpector]_SkillIntense("", float) = 0
		[HideInInSpector]_TransitionTime("", float) = 0
		[HideInInSpector]_IntervalTime("", float) = 0
		[HideInInSpector]_SkillDirection("", int) = 0
		[HideInInSpector]_SampleChannel("", int) = 0
	}

	SubShader{
		Tags{ "Queue" = "Overlay" "RenderPipeline" = "LightweightPipeline" "RenderType" = "Opaque" "IgnoreProjector" = "True" }
		Cull off

		HLSLINCLUDE
#include "/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "/Packages/com.unity.render-pipelines.universal/ShaderLibrary/Input.hlsl"

			TEXTURE2D(_InteractiveTex);		SAMPLER(sampler_InteractiveTex);
			TEXTURE2D(_MaskTex);			SAMPLER(sampler_MaskTex);

			CBUFFER_START(UnityPerMaterial)
				half4 _InteractiveTex_TexelSize;
				half4 _MaskTex_TexelSize;
				half4 _Dif;
				//half4 _WorldOffset;
				half4 _CenterPos;
				half _SkillIntense;
				half _TransitionTime;
				half _IntervalTime;
				int _SkillDirection;
				int _SampleChannel;	
			CBUFFER_END
		ENDHLSL

		Pass
		{
			Tags{ "LightMode" = "LightweightForward" }
			Name "GeometryGrassInteractiveMove"
			Cull off
			ZWrite Off
			ZTest Always
			
		HLSLPROGRAM
		//#pragma enable_d3d11_debug_symbols
#pragma vertex vert
#pragma fragment frag
		//#pragma multi_compile_instancing
#pragma target 3.0
			struct appdata_full {
				float4 vertex : POSITION;
				float4 tangent : TANGENT;
				float3 normal : NORMAL;
				float4 texcoord : TEXCOORD0;
				float4 texcoord1 : TEXCOORD1;
				float4 texcoord2 : TEXCOORD2;
				float4 texcoord3 : TEXCOORD3;
				half4 color : COLOR;
				UNITY_VERTEX_INPUT_INSTANCE_ID   
			};
			struct v2f
			{
				half4 pos : SV_POSITION;
				half2 uv : TEXCOORD0;
				half2 prevUV : TEXCOORD1;
				//half3 worldPos : TEXCOORD2;
			};

			struct PSOutput
			{
				half4 interactive : COLOR0;
			};

			v2f vert(appdata_full v)
			{

				v2f o;
				//UNITY_SETUP_INSTANCE_ID(v);
				o.pos = half4(v.vertex.xyz, 1.0);
				//o.pos.x += 1.0;
				//o.pos.y += 1.0;
				o.uv = v.texcoord.xy;
		#if UNITY_UV_STARTS_AT_TOP
				// DX 
				o.uv.y = 1.0 - o.uv.y;
				_Dif.z *= -1;
				// OpenGL, don't need 1.0 - y
		#endif
				o.prevUV = o.uv + _Dif.xz * _InteractiveTex_TexelSize.xy;
				return o;
			}

			PSOutput frag(v2f IN)
			{
				half4 prevVInteractive = half4(0, 0, 0, 0);
				if (IN.prevUV.x >= 0 && IN.prevUV.x < 1 && IN.prevUV.y >= 0 && IN.prevUV.y < 1)
				{
					prevVInteractive = SAMPLE_TEXTURE2D(_InteractiveTex, sampler_InteractiveTex, IN.prevUV);
				}

		#if 0
				// reset begin
				prevVInteractive = half4(0, 0, 0, 0);
				// rest end
		#endif
				PSOutput psOut;
				psOut.interactive = prevVInteractive;
				return psOut;
			}
		ENDHLSL
		}

		Pass
		{
			Name "InteractiveMarkRange"
			Tags{ "LightMode" = "LightweightForward" }
			ZWrite Off
			Cull off
			Lighting Off
			ZTest Always
			Blend One One

			HLSLPROGRAM
			//#pragma enable_d3d11_debug_symbols
	#pragma vertex vert
	#pragma fragment frag
	//#pragma multi_compile_instancing
	#pragma multi_compile INSTANCING_ON
	#pragma target 3.0
			struct appdata_full {
				float4 vertex : POSITION;
				float4 tangent : TANGENT;
				float3 normal : NORMAL;
				float4 texcoord : TEXCOORD0;
				float4 texcoord1 : TEXCOORD1;
				float4 texcoord2 : TEXCOORD2;
				float4 texcoord3 : TEXCOORD3;
				half4 color : COLOR;
				UNITY_VERTEX_INPUT_INSTANCE_ID
			};
			struct v2f
			{
				half4 pos : SV_POSITION;
				half2 uv : TEXCOORD0;
				UNITY_VERTEX_INPUT_INSTANCE_ID//necessary only if you want to access properties in fragment shader
			};

			struct PSOutput
			{
				half4 interactive : COLOR0;
			};

			UNITY_INSTANCING_BUFFER_START(Props)
			UNITY_DEFINE_INSTANCED_PROP(half4, _maskStartUVSize)
			UNITY_DEFINE_INSTANCED_PROP(half4, _interactiveCastSkillPos)
			UNITY_DEFINE_INSTANCED_PROP(half4, _interactiveType)
			UNITY_INSTANCING_BUFFER_END(Props)

			v2f vert(appdata_full v)
			{

				v2f o;
				UNITY_SETUP_INSTANCE_ID(v);
				UNITY_TRANSFER_INSTANCE_ID(v, o);//necessary only if you want to access properties in fragment shader
				o.pos = mul(UNITY_MATRIX_M, half4(v.vertex.xyz, 1.0));
				//o.pos = half4(v.vertex.xyz, 1.0);

				////keep skill range stay in place that being cast
				////_interactivePos is On_Weapon params character's worldpos when cast skill, _CenterPos.xz is character's current worldpos;
				half4 interactivePos = UNITY_ACCESS_INSTANCED_PROP(Props, _interactiveCastSkillPos);
				//如果256*256的RT范围设置为51.2m*51.2m  <--> 2*2 in NDC，那么1m <--> 5pixel <--> 1/25.6 in NDC;
				//如果512*512的RT范围设置为51.2m*51.2m  <--> 2*2 in NDC，那么1m <--> 10pixel <--> 1/25.6 in NDC;所以从世界坐标单位m到NDC转换要除以25.6；
				half posOffsetX = (interactivePos.x - _CenterPos.x) / 25.6;
				half posOffsetZ = (interactivePos.z - _CenterPos.z) / 25.6;
				o.pos.x += posOffsetX;
				//- is consistent with openGL view space camera look at minus Z axis ??
				o.pos.y += posOffsetZ;

				o.uv = v.texcoord.xy;	// now the (0, 0) is left top
				half4 maskStartUVSize = UNITY_ACCESS_INSTANCED_PROP(Props, _maskStartUVSize);
				o.uv *= maskStartUVSize.zw;
				o.uv += maskStartUVSize.xy;
				o.uv *= _MaskTex_TexelSize.xy;

		//Untiy采样普通纹理时统一（0，0）在左下角，采样RT时需要变换y轴；以下旧代码有误因此注释掉
		//#if UNITY_UV_STARTS_AT_TOP
		//		// DX 
		//		o.uv.y = 1.0 - o.uv.y;	// after this, the (0, 0) is left bottom
		//#else
		//		// OpenGL, don't need 1.0 - y
		//
		//#endif

				return o;
			}

			PSOutput frag(v2f IN)
			{
				UNITY_SETUP_INSTANCE_ID(IN);//necessary only if you want to access properties in fragment shader
				//uv (0, 0) is left bottom
				half4 type = UNITY_ACCESS_INSTANCED_PROP(Props, _interactiveType);
				//half4 maskValue = tex2D(_MaskTex, IN.uv);
				//maskValue = _SkillIntense* maskValue.r * type;

				////cmj: debug for weapon spread
				half4 maskValue = half4(0, 0, 0, 0);
				half4 maskStartUVSize = UNITY_ACCESS_INSTANCED_PROP(Props, _maskStartUVSize);
				half uStart = maskStartUVSize.x * _MaskTex_TexelSize.x;
				half vStart = maskStartUVSize.y * _MaskTex_TexelSize.y;
				half uStart2End = maskStartUVSize.z * _MaskTex_TexelSize.x;
				half vStart2End = maskStartUVSize.w * _MaskTex_TexelSize.y;
				//half uTemp = uStart + _TransitionTime * uStart2End;
				half vTemp = vStart + _TransitionTime * vStart2End;
				half uCenter = uStart + uStart2End * 0.5;
				half vCenter = vStart + vStart2End * 0.5;
				//half lastTime = saturate(_TransitionTime - _IntervalTime);
		//Untiy采样普通纹理时统一（0，0）在左下角，采样RT时需要变换y轴；以下旧代码有误因此注释掉
		//#if UNITY_UV_STARTS_AT_TOP
		//		vStart = 1 - vStart;
		//		vStart2End *= -1;
		//		vTemp = vStart + (1 - _TransitionTime) * vStart2End;
		//		vCenter = 1 - vCenter;
		//
		//#endif

				half4 tex = SAMPLE_TEXTURE2D(_MaskTex, sampler_MaskTex, IN.uv);

				if (_SampleChannel == 0)
					tex = half4(tex.r, tex.r, tex.r, tex.r);
				else if(_SampleChannel == 1)
					tex = half4(tex.g, tex.g, tex.g, tex.g);
				else if(_SampleChannel == 2)
					tex = half4(tex.b, tex.b, tex.b, tex.b);
				else if(_SampleChannel == 3)
					tex = half4(tex.a, tex.a, tex.a, tex.a);

				//cmj: 0为从中心扩散, 1为从左向右，2为从右往左横扫, 3为从下往上扫, 4为从上往下扫
				if (_SkillDirection == 0) {
					//cmj: debug for fire spread

					//uStart2End * uStart2End/4是maskTex中的圆 以uv坐标计算的R的平方
					if (pow((IN.uv.x - uCenter), 2) + pow((IN.uv.y - vCenter), 2) <= _TransitionTime * uStart2End * uStart2End*0.25)
						maskValue = tex;

				}
				else if (_SkillDirection == 1) {
					half uTemp = uStart + _TransitionTime * uStart2End;

					if (IN.uv.x < uTemp)
						maskValue = tex;
				}
				else if (_SkillDirection == 2) {
					//反转uv.x： 如0.25->0.5 变为 0.5->0.25
					half uTemp = uStart + (1 - _TransitionTime) * uStart2End;

					//IN.uv.x = -1 * IN.uv.x + 2 * uStart + uStart2End;

					if (IN.uv.x > uTemp)
						maskValue = tex;

				}
				else if (_SkillDirection == 3) {
					if (IN.uv.y < vTemp)
						maskValue = tex;
				}
				else if (_SkillDirection == 4) {
					IN.uv.y = -1 * IN.uv.y + 2 * vStart + vStart2End;
					if (IN.uv.y < vTemp)
						maskValue = tex;

				}

				//_SkillIntense 可配置参数是为了让草一下子不被砍完
				maskValue = _SkillIntense * maskValue * type;

				PSOutput psOut;
				psOut.interactive = maskValue;
				return psOut;
			}
		ENDHLSL
		}

	}
}

